Infrastructure configs for GMKtec K11 (Docker, vLLM, LocalAI, ComfyUI, control-plane, gpu-fan agent, Server UI with CLI/file explorer/GPU fan curve). Co-authored-by: Cursor <cursoragent@cursor.com>
8.5 KiB
06 — Sterowanie wentylatorami GPU
Cel rozdziału: skonfigurować sterowanie wentylatorami RTX 3090 Ti na headless serwerze — krzywa temp → prędkość, web UI w sieci lokalnej, usługa systemd.
Szacowany czas: 15–20 minut
Wymagania: ukończony rozdział 02 — Sterowniki NVIDIA (nvidia-smi działa)
Spis treści
- Dlaczego własny stack
- Weryfikacja punktu startowego
- Instalacja
- Web UI w sieci lokalnej
- Krzywa max cooling
- Zarządzanie usługą
- Weryfikacja pod obciążeniem
- Troubleshooting
- Następny krok
1. Dlaczego własny stack
Na headless Ubuntu nie działają narzędzia oparte na nvidia-settings + CoolBits (wymagają display servera).
Od sterownika NVIDIA 520+ sterowanie wentylatorami GeForce jest dostępne przez NVML — działa bez monitora i bez X11.
Stack stacks/gpu-fan/:
- daemon NVML (Python +
pynvml) - web UI do edycji krzywej
- preset agresywny pod długie obciążenie LocalAI / vLLM
nvidia-smi pokazuje tylko odczyty — nie ustawia prędkości wentylatorów.
2. Weryfikacja punktu startowego
nvidia-smi --query-gpu=name,driver_version,temperature.gpu,fan.speed --format=csv,noheader
# Oczekiwane:
# NVIDIA GeForce RTX 3090 Ti, 595.x, <temp>, <fan> %
python3 -c "import pynvml; pynvml.nvmlInit(); h=pynvml.nvmlDeviceGetHandleByIndex(0); print(pynvml.nvmlDeviceGetName(h)); pynvml.nvmlShutdown()"
Jeśli ModuleNotFoundError: pynvml — install.sh doinstaluje zależności. Możesz też:
sudo apt install -y python3-pynvml
3. Instalacja
Z katalogu repozytorium na serwerze:
cd ~/cursor/ubuntu-bare-metal/stacks/gpu-fan
cp .env.example .env
# opcjonalnie: edytuj GPU_FAN_PORT, API_KEY
sudo scripts/install.sh
sudo scripts/enable-lan.sh
sudo systemctl status gpu-fan
Co robi install.sh:
| Krok | Efekt |
|---|---|
apt install python3-venv |
Środowisko Python |
Kopiuje pliki do /opt/gpu-fan |
Kod aplikacji |
Tworzy /etc/gpu-fan/curve.json |
Domyślna krzywa max cooling |
systemctl enable gpu-fan |
Start przy bootcie |
Logi:
journalctl -u gpu-fan -f
4. Web UI w sieci lokalnej
Domyślnie UI nasłuchuje na 0.0.0.0:8090 — dostępne z każdego urządzenia w LAN.
# IP serwera
hostname -I | awk '{print $1}'
# API key
grep ^API_KEY= /opt/control-plane/.env
W przeglądarce na laptopie / telefonie w tej samej sieci:
http://192.168.100.5:8090/?api_key=TWÓJ_KLUCZ_Z_.env
Klucz można też podać w promptcie UI przy pierwszym wejściu (bez ?api_key= w URL).
Tylko localhost (opcjonalnie)
W /opt/control-plane/.env:
GPU_FAN_HOST=127.0.0.1
API_KEY=
sudo systemctl restart gpu-fan
Dostęp przez SSH tunnel:
ssh -L 8090:127.0.0.1:8090 tomasz-syn-grzegorza@gmktec-k11
Otwórz: http://localhost:8090
Funkcje UI
- Wykres krzywej — przeciąganie punktów; podziałka temperatury (°C) i prędkości (%), siatka pomocnicza i linijki z kreskami na zewnętrznych krawędziach osi
- Tabela temp / speed
- Status live: temperatura, wentylatory, moc, wykorzystanie GPU
- Zapisz krzywą — zapis do
/etc/gpu-fan/curve.json - Tryb auto — oddaje sterowanie driverowi NVIDIA
- Manual 100% — awaryjne pełne obroty
API key
Przy dostępie z LAN API_KEY jest wymagany (generowany przy install.sh lub ustaw ręcznie w .env):
sudo nano /opt/control-plane/.env
sudo systemctl restart gpu-fan
5. Krzywa max cooling
Domyślny plik /etc/gpu-fan/curve.json:
{
"30": 50,
"40": 65,
"50": 80,
"55": 90,
"60": 100,
"70": 100
}
Edycja ręczna:
sudo nano /etc/gpu-fan/curve.json
sudo systemctl reload gpu-fan
Ograniczenia API NVIDIA
| Wartość | Znaczenie |
|---|---|
| 0% | Oddaj sterowanie driverowi (auto) |
| 1–29% | Niedozwolone przez API |
| 30–100% | Dozwolone w trybie manual |
RTX 3090 Ti w trybie auto może mieć 0 RPM przy niskiej temperaturze — to normalne zachowanie karty.
6. Zarządzanie usługą
sudo systemctl start gpu-fan # start
sudo systemctl stop gpu-fan # stop + przywrócenie auto
sudo systemctl restart gpu-fan # restart
sudo systemctl reload gpu-fan # przeładuj curve.json (SIGHUP)
Test API z serwera:
curl -s http://127.0.0.1:8090/api/status | python3 -m json.tool
curl -s -X POST http://127.0.0.1:8090/api/mode \
-H 'Content-Type: application/json' \
-d '{"mode":"manual","speed":100}'
curl -s -X POST http://127.0.0.1:8090/api/mode \
-H 'Content-Type: application/json' \
-d '{"mode":"auto"}'
7. Weryfikacja pod obciążeniem
7.1 Idle
watch -n2 'curl -s http://127.0.0.1:8090/api/status | python3 -m json.tool'
W trybie curve przy ~40°C oczekuj target_speed zgodnego z krzywą (np. ~50–65%).
7.2 Obciążenie GPU
Uruchom inference (LocalAI lub vLLM), np.:
# LocalAI (jeśli działa)
curl -s http://localhost:8070/v1/models
# lub krótki stress (opcjonalnie, wymaga cuda w kontenerze)
# docker run --rm --gpus all nvidia/cuda:12.0-base nvidia-smi dmon -s puc -d 1 -c 30
Obserwuj w UI lub przez API:
temperature_crośnie pod loademtarget_speed_pctpodąża za krzywąfan_speeds_pctdążą dotarget_speed_pct
7.3 Graceful shutdown
sudo systemctl stop gpu-fan
nvidia-smi --query-gpu=fan.speed --format=csv,noheader
Po stopie usługi wentylatory powinny wrócić do polityki drivera (auto).
Checklist
systemctl status gpu-fan— active (running)- Web UI dostępne z LAN (
http://<ip>:8090) - Zapis krzywej w UI działa
- Pod loadem temp rośnie, wentylatory przyspieszają
- Po
stop— tryb auto drivera
8. Troubleshooting
8.1 Insufficient Permissions
Sterowanie wentylatorami wymaga root. Uruchamiaj przez systemd lub sudo scripts/start.sh.
8.2 Failed to initialize NVML: Driver/library version mismatch
Po aktualizacji kernela lub sterownika:
sudo reboot
8.3 Wentylatory nie schodzą poniżej 30%
To ograniczenie API NVIDIA w trybie manual — nie błąd aplikacji. Dla ciszy przy idle użyj Tryb auto w UI.
8.4 Port 8090 zajęty / address already in use
Nie zmieniaj portu na 8091, 8092… — to tylko maskuje problem. Przy kolejnym podwójnym starcie następny port też będzie zajęty.
Diagnostyka:
cd ~/cursor/ubuntu-bare-metal/stacks/gpu-fan
scripts/status.sh
sudo ss -tlnp | grep -E ':809[0-9]'
jobs -l # zawieszone Ctrl+Z w tej sesji SSH
Czyszczenie:
sudo scripts/status.sh --cleanup
sudo systemctl start gpu-fan
Typowe przyczyny:
| Objaw | Przyczyna | Rozwiązanie |
|---|---|---|
Błąd po systemctl restart + start.sh |
Dwie instancje | Używaj albo systemd albo start.sh |
[n]+ Stopped start.sh w terminalu |
Ctrl+Z zamiast Ctrl+C | kill %n lub sudo scripts/status.sh --cleanup |
| Port zajęty po reboot | gpu-fan.service włączone (enable) |
Normalne — nie uruchamiaj drugiej kopii |
Zmiana portu w repo .env bez efektu |
Produkcja czyta /opt/control-plane/.env |
Edytuj /opt/control-plane/.env lub uruchom setup-control-plane-env.sh |
Po zmianach w kodzie UI (np. monitoring GPU):
sudo scripts/install.sh && sudo systemctl restart gpu-fan
Foreground debug (tylko gdy systemd zatrzymany):
sudo systemctl stop gpu-fan
sudo scripts/start.sh
# Zakończ: Ctrl+C (nie Ctrl+Z!)
8.5 Krzywa odrzucona (400)
- 3–7 punktów
- temperatury rosnąco, unikalne
- prędkość: 0 lub 30–100
9. Następny krok
Po przejściu checklisty:
- Zostaw
gpu-fanwłączony przy workloadach AI (LocalAI, ComfyUI, vLLM). - Rozdział 07 — ComfyUI stack — generowanie obrazów w Dockerze.
- Rozważ
API_KEYprzed ewentualnym wystawieniem portu w rozdziale firewall (08).
Powrót do roadmapy: README.md
Podsumowanie
Po ukończeniu rozdziału:
- Działa
gpu-fan.servicena hoście (NVML, root) - Krzywa w
/etc/gpu-fan/curve.json - Web UI na 0.0.0.0:8090 (dostęp z sieci lokalnej, z API key)
- Stop usługi przywraca auto drivera NVIDIA