Power limits en fancurves instellen voor GPU-servers
Wie een eigen machine inricht voor lokale taalmodellen bevindt zich in de fase van hardwarebeheer en operationele optimalisatie: de stap direct na het selecteren van componenten en het installeren van de basissoftware. Raadpleeg voor de initiële componentkeuze het fundament in het overzicht over welke hardware nodig is voor lokale LLM's om te zien welke kaarten en geheugenbandbreedtes geschikt zijn voor inferentietaken. Zodra de drivers geïnstalleerd zijn op een Linux-systeem, zoals stapsgewijs beschreven in de handleiding over lokale LLM's draaien op Linux, blijkt in de praktijk dat standaard fabrieksinstellingen zelden optimaal zijn voor continue AI-inferentie, serverprocessen of langdurige batchverwerking.
Standaard consumer- en workstation-GPU's zijn vanuit de fabriek afgesteld om agressief naar de hoogste kloksnelheden te boosten tot het maximale thermische of elektrische limiet wordt bereikt. Bij het genereren van tokens levert die laatste tien tot twintig procent elektrisch vermogen echter vrijwel geen merkbare versnelling op, terwijl de warmteontwikkeling en het geluidsniveau exponentieel toenemen. In deze gids doorlopen we hoe het instellen van vermogensbegrenzingen (power limits) en op maat gemaakte ventilatorkrommes (fancurves) zorgt voor een fluisterstille, thermisch stabiele en energie-efficiënte serveromgeving.
Waarom fabrieksinstellingen suboptimaal zijn voor AI-inferentie
Moderne grafische processors schalen hun interne klokfrequenties dynamisch op basis van algoritmes zoals NVIDIA GPU Boost. Deze mechanismen verhogen het voltage en de core-kloksnelheid lineair totdat het vooraf ingestelde Thermal Design Power (TDP) plafond wordt geraakt. Een moderne grafische kaart met een fabrieks-TDP van 350 watt of 450 watt verbruikt onder standaardinstellingen continu deze maximale capaciteit tijdens zware prompt-verwerking (prefill) en token-generatie.
Bij taalmodellen is de doorvoersnelheid in de autoregressieve generatiefase echter primair begrensd door de geheugenbandbreedte van het VRAM, en veel minder door de pure rekenkracht van de CUDA- of Tensor-cores. Voor elke gegenereerde token moeten immers alle modelgewichten opnieuw vanuit het videogeheugen naar de rekeneenheden worden getransfereerd. Hierdoor ontstaat een wet van afnemende meeropbrengst: het verhogen van het vermogen van 280 watt naar 450 watt levert vaak slechts een minieme fractie extra tokensnelheid op, terwijl het stroomverbruik met ruim zestig procent stijgt. De theoretische achtergrond van deze kostenstructuur is doorgerekend in de analyse van wat het stroomverbruik van lokale AI kost.
Daarnaast leidt ongebreidelde hitteontwikkeling tot thermische degradatie en plotselinge thermische throttling. Wanneer de GPU-kerntemperatuur de 83 graden Celsius nadert of het VRAM warmer wordt dan 95 tot 105 graden, grijpt het BIOS in door de klokken abrupt omlaag te schalen. Dit veroorzaakt grillige responstijden, verhoogde latency-uitschieters en onnodige mechanische slijtage van ventilatorkogellagers en printplaatcomponenten in een 24/7 serveromgeving.
NVIDIA Persistence Mode en vermogenslimieten via nvidia-smi
Om wijzigingen via de command-line interface direct en betrouwbaar door te voeren, vormt de tool nvidia-smi de primaire ingang. Standaard initialiseert de Linux-driver de GPU-status pas wanneer een proces een actieve CUDA-context opent, en sluit deze status direct af zodra het proces stopt. Hierdoor gaan dynamisch ingestelde vermogenslimieten na elke losse taak of API-aanroep direct verloren. Het aanzetten van Persistence Mode is daarom de absolute eerste vereiste.
# Activeer persistence mode voor alle aanwezige GPU's
sudo nvidia-smi -pm 1
# Controleer de huidige, minimale en maximale vermogenslimieten
nvidia-smi -q -d POWER
De uitvoer van het bovenstaande query-commando toont drie cruciale waarden: Min Power Limit, Max Power Limit en Default Power Limit. Een high-end 450W-kaart toont bijvoorbeeld typisch een minimum van 150 watt, een standaardwaarde van 450 watt en een hardwarematig maximum van 600 watt. Nadat persistence is ingeschakeld, kan voor elke kaart een specifiek vermogenslimiet in watt worden vastgelegd met de vlag -pl (power limit). Bij een multi-GPU configuratie kan per kaart een index worden meegegeven via de parameter -i.
# Stel het vermogenslimiet van GPU 0 in op 280 Watt
sudo nvidia-smi -i 0 -pl 280
# Stel het vermogenslimiet van GPU 1 in op 260 Watt
sudo nvidia-smi -i 1 -pl 260
Het effect van deze instelling is onmiddellijk actief op hardwareniveau. De spanningsregelaar op de printplaat past direct de maximale spanningstoevoer aan, waardoor de kerntemperatuur binnen korte tijd stabiliseert op een aanzienlijk lager niveau zonder dat er een herstart van het model of de server nodig is.
Het thermodynamische verband tussen wattage, temperatuur en tokensnelheid
Het vaststellen van het ideale wattage voor een specifieke server vereist inzicht in het verband tussen rekenintensiteit, geheugenverzadiging en thermische dissipatie. Tijdens de initiële prompt-verwerking (de prefill-fase) worden input-tokens parallel verwerkt via dichte matrixvermenigvuldigingen (GEMM), waarbij de Tensor-cores maximaal worden benut. In deze korte fase heeft een hoger wattage een meetbaar positief effect op de verwerkingstijd van grote contexten.
Tijdens de autoregressieve decode-fase (het token voor token genereren van tekst) verschuift het knelpunt echter volledig naar de geheugenbus. De rekeneenheden wachten constant op het laden van gewichten uit het GDDR6(X)-geheugen. Het toevoeren van extra vermogen naar de GPU-kern verhoogt in deze fase voornamelijk de temperatuur en het lekstroomverlies (joule heating), zonder dat de geheugenbandbreedte evenredig toeneemt. Wie wil evalueren hoe deze dynamiek zich verhoudt tot het totale systeemverbruik, vindt de geschikte meetmethodologie in het artikel over het energieverbruik van een lokale LLM-opstelling meten.
Onderstaand rekenmodel illustreert het theoretische en kwalitatieve verloop van energie-efficiëntie bij verschillende niveaus van vermogensbegrenzing op een high-end GPU met een standaardvermogen van 450 watt:
| Instelling (% van TDP) | Prefill-impact | Generatie-impact (decode) | Thermisch profiel | Relatieve efficiëntiewinst |
|---|---|---|---|---|
| 100% (450W - Standaard) | Maximale basissnelheid | Volledige busverzadiging | Hoge kerntemperatuur, snelle ventilatorrespons | Basisniveau (1.0x) |
| 75% - 80% (~350W) | Verwaarloosbaar (< 2% verlies) | Geen merkbaar verschil (< 1% verlies) | Duidelijke temperatuurdaling van 5-8°C | Ca. 25% gunstiger energieprofiel |
| 60% - 65% (~280W) | Lichte vertraging (5-8% verlies) | Zeer beperkt verlies (2-4% verlies) | Stabiele lage temperaturen, stille ventilatoren | Ca. 45% tot 50% gunstiger energieprofiel |
| 50% (~225W) | Merkbare vertraging (15-25% verlies) | Zichtbaar snelheidsverlies (10-15% verlies) | Minimale warmteafgifte, laagste geluidsdruk | Maximale efficiëntie per watt, lagere piekcapaciteit |
Voor continue inferentieservers en interactieve API-endpoints ligt het optimale operationele punt doorgaans tussen de 60% en 75% van het standaardvermogen. Hierdoor blijft de generatiesnelheid nagenoeg gelijk aan fabrieksinstellingen, terwijl de totale warmteproductie drastisch afneemt.
Instellingen persistent maken met een systemd-service
Commando's die handmatig worden ingevoerd via nvidia-smi overleven een herstart van het besturingssysteem niet. Om te garanderen dat de server na een geplande herstart, stroomonderbreking of automatische kernel-update direct weer in de geoptimaliseerde staat opstart, richten we een dedicated systemd unit in.
Maak een nieuw servicebestand aan in de centrale configuratiemap van systemd:
# /etc/systemd/system/nvidia-power-limit.service
[Unit]
Description=NVIDIA GPU Power Limits en Persistence Mode
After=syslog.target network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/nvidia-smi -pm 1
ExecStart=/usr/bin/nvidia-smi -pl 280
[Install]
WantedBy=multi-user.target
Indien het systeem beschikt over meerdere verschillende videokaarten, kunnen meerdere ExecStart-regels onder elkaar worden geplaatst, waarbij per kaartindex een specifiek wattage wordt toegekend:
# Multi-GPU variant voor gemengde kaarten
ExecStart=/usr/bin/nvidia-smi -i 0 -pl 280
ExecStart=/usr/bin/nvidia-smi -i 1 -pl 240
Activeer en start de service vervolgens via het servicebeheer van Linux:
sudo systemctl daemon-reload
sudo systemctl enable nvidia-power-limit.service
sudo systemctl start nvidia-power-limit.service
# Controleer of de service succesvol is uitgevoerd
systemctl status nvidia-power-limit.service
Fancurves beheren op headless Linux-servers
Op desktopinstallaties met een grafische schil zoals GNOME of KDE kan men eenvoudig ventilatorkrommes aanpassen via GUI-tools zoals GreenWithEnvy. Op een headless productieserver ontbreekt echter een actieve beeldschermserver. De officiële NVIDIA Linux-stuurprogramma's vereisen van oudsher interactie met een actieve X11-server om ventilatorregelingen via de zogenaamde Coolbits vlag toe te staan.
Om handmatige ventilatorsturing mogelijk te maken op een server zonder fysiek aangesloten monitor, configureren we een virtuele X-server (dummy X-server) met Coolbits-ondersteuning:
# Genereer een minimale xorg.conf met Coolbits (bitmask 28 voor klok- en fancontrole)
sudo nvidia-xconfig --cool-bits=28 --allow-empty-initial-configuration --enable-all-gpus
Vervolgens kan een virtuele Xorg-sessie op de achtergrond worden gestart, waarna de ventilatorkromme kan worden aangestuurd met nvidia-settings:
# Start X op display :0 in de achtergrond
sudo Xorg :0 &
# Schakel handmatige ventilatorsturing in voor GPU 0
DISPLAY=:0 XAUTHORITY=/var/run/lightdm/root/:0 nvidia-settings -a "[gpu:0]/GPUFanControlState=1"
# Zet de ventilatorsnelheid vast op een constant percentage van 65%
DISPLAY=:0 XAUTHORITY=/var/run/lightdm/root/:0 nvidia-settings -a "[fan:0]/GPUTargetFanSpeed=65"
Voor moderne headless omgevingen waar het draaien van een Xorg-daemon als ongewenste ballast wordt gezien, zijn er lichte alternatieven beschikbaar zoals nvfancontrol of scripts die rechtstreeks communiceren met de NVML (NVIDIA Management Library) C-API. Deze daemons draaien volledig binnen user-space of als native service en vereisen geen X11-architectuur.
Thermische dynamiek en asymmetrische belasting bij multi-GPU setups
Wanneer twee of meer grafische kaarten direct naast elkaar in PCIe-sloten worden geplaatst, ontstaat er een significante asymmetrische thermische belasting. De bovenste kaart trekt doorgaans de voorverwarmde afvoerlucht van de onderste kaart aan, waardoor de temperatuur van de bovenste GPU bij een identiek ingesteld wattage tien tot vijftien graden hoger oploopt. Wie meerdere kaarten in één behuizing combineert, vindt diepgaande instructies over PCIe-slotconfiguraties en bandbreedteverdeling in de gids over twee GPU's combineren voor grotere lokale taalmodellen.
In een dergelijke opstelling is het toepassen van identieke power limits een klassieke ontwerpfout. Een veel robuustere strategie bestaat uit gedifferentieerde vermogenslimieten:
| GPU Positie | Fysieke Beperking | Aanbevolen Power Limit | Ventilatorprofiel |
|---|---|---|---|
| GPU 0 (Bovenste sleuf) | Ontvangt warme lucht van GPU 1 | 240W - 260W (-40%) | Agressief (70% bij 60°C) |
| GPU 1 (Onderste sleuf) | Vrije aanzuig van verse lucht | 280W - 300W (-33%) | Matig (55% bij 60°C) |
Tijdens intensieve inferentie met productieframeworks zoals vLLM of Ollama zorgt deze evenwichtige temperatuurbalans voor consistente, voorspelbare latency zonder thermische throttling-pieken. Meer over het gedrag en de prestaties van deze softwarestacks onder continue belasting is te vinden in de review van vLLM versus Ollama voor productie op eigen servers.
Automatisering en dynamische bewaking met Python en NVML
Voor geavanceerd beheer kan een op maat gemaakte Python-achtergronddaemon worden ingericht die de officiële NVML-bindings (pynvml) gebruikt. Het grote voordeel hiervan is dat de sturing niet alleen kan reageren op de kerntemperatuur van de chip, maar tevens op de VRAM-temperatuur (Memory Junction Temperature). Bij intensieve kwantisatie- en tensorberekeningen kan het videogeheugen namelijk heet worden terwijl de GPU-kern zelf relatief koel blijft.
import time
import subprocess
from pynvml import *
nvmlInit()
device_count = nvmlDeviceGetCount()
# Temperatuurgrenzen voor dynamische ventilatorkromme
FAN_CURVE = [
(45, 35), # <= 45°C -> 35% fanspeed
(55, 50), # 55°C -> 50% fanspeed
(65, 70), # 65°C -> 70% fanspeed
(75, 85), # 75°C -> 85% fanspeed
(82, 100) # >= 82°C -> 100% fanspeed
]
def bereken_fanspeed(temp):
for t_grens, speed in FAN_CURVE:
if temp <= t_grens:
return speed
return 100
def monitor_en_stuur():
for i in range(device_count):
handle = nvmlDeviceGetHandleByIndex(i)
temp_core = nvmlDeviceGetTemperature(handle, NVML_TEMPERATURE_GPU)
power_mw = nvmlDeviceGetPowerUsage(handle)
power_w = power_mw / 1000.0
doel_speed = bereken_fanspeed(temp_core)
print(f"GPU {i}: Kern={temp_core}°C | Verbruik={power_w:.1f}W | Fan Doel={doel_speed}%")
if __name__ == "__main__":
try:
print("NVML Monitor Daemon gestart...")
while True:
monitor_en_stuur()
time.sleep(3)
except KeyboardInterrupt:
print("Afsluiten...")
finally:
nvmlShutdown()
Met dergelijke scripts kan tevens een veiligheidslus worden ingebouwd: wanneer de kerntemperatuur onverhoopt een kritieke drempel overschrijdt, kan het script via een subprocess-call naar nvidia-smi -pl automatisch het vermogenslimiet tijdelijk met nog eens 30 watt verlagen tot de componenten zijn afgekoeld.
Valkuilen, hardwarebeperkingen en praktische risico's
Hoewel het instellen van vermogensbegrenzingen en aangepaste fancurves over het algemeen zeer veilig is, zijn er enkele belangrijke randgevallen en hardwarematige beperkingen waarmee rekening moet worden gehouden:
1. Minimale vermogensdrempels: Elke videokaart heeft in zijn firmware een harde ondergrens (Min Power Limit) ingebouwd. Het is niet mogelijk om een 450W-kaart via nvidia-smi terug te schroeven naar 50 watt; de driver weigert waarden onder het minimum (veelal rond de 150W tot 200W). Wie een nog lager verbruik wenst tijdens inactiviteit, moet vertrouwen op de automatische C-states en PCIe ASPM (Active State Power Management) energiebesparende profielen van het moederbord.
2. VRAM Junction versus Core-temperatuur: Standaard fancurves in het BIOS van consumentenkaarten kijken uitsluitend naar de GPU-kerntemperatuur. Tijdens lange promptsessies kan het GDDR6X-geheugen aan de achterzijde van een printplaat aanzienlijk warmer worden dan de kern. Zorg daarom altijd voor voldoende actieve airflow over de backplate van de videokaart.
3. Akoestische slijtage en hysterese: Ventilatoren die voortdurend heen en weer schakelen tussen 40% en 80% slijten aanzienlijk sneller door wisselende mechanische torsiekrachten. Bouw in zelfgeschreven software altijd een hysterese in van minimaal 3 tot 5 graden, zodat de ventilatorsnelheid niet oscilleert bij minimale temperatuurschommelingen.
Stappenplan voor een betrouwbare productieconfiguratie
Het structureel optimaliseren van GPU-servers voor AI-inferentie laat zich samenvatten in een overzichtelijk stappenplan:
Stap 1: Activeer Persistence Mode. Zorg dat de GPU-driver status vasthoudt met sudo nvidia-smi -pm 1 om configuratieverlies tussen API-calls te voorkomen.
Stap 2: Bepaal de vermogenslimiet. Verlaag het wattage stapsgewijs (naar circa 60% tot 75% van het fabrieks-TDP) en controleer of de tokensnelheid acceptabel blijft voor de specifieke workload.
Stap 3: Borging via systemd. Schrijf de instellingen weg in een /etc/systemd/system/nvidia-power-limit.service unit zodat het beleid herstarts overleeft.
Stap 4: Actieve koeling bewaken. Stel op multi-GPU machines asymmetrische vermogenslimieten in en zorg via Xorg-Coolbits of een NVML-daemon voor adequate ventilatorkrommes die oververhitting van het videogeheugen voorkomen.
Met deze aanpak draait een lokale AI-server stiller, koeler en aanzienlijk zuiniger, met een maximale levensduur van de hardware en een stabiele responstijd voor alle aangesloten gebruikers.


