22 oct. 2026 · guide · matos & conso
undervolter une 3090 ou une 3080 ti sous linux, sans perdre de perf
le pas à pas que j'utilise sur ma box : bloquer la fréquence, décaler la courbe tension/fréquence avec NVML, vérifier sous vraie charge, puis rendre ça automatique au démarrage
avant de commencer
sous windows, on undervolte une carte nvidia en tirant la courbe dans MSI Afterburner. sous linux il n'y a pas d'outil équivalent, et le pilote ne laisse pas toucher directement à la tension. on va donc obtenir le même effet par un détour en deux temps :
- on bloque la fréquence maximale de la carte, pour qu'elle ne monte jamais dans la zone où elle consomme beaucoup pour très peu de gain ;
- on décale toute la courbe tension/fréquence vers le haut. la carte atteint alors la fréquence bloquée en demandant moins de tension qu'avant, et c'est ça qui fait baisser la conso.
c'est différent d'une simple baisse de la limite de puissance (nvidia-smi -pl), qui oblige la carte à ralentir dès qu'elle touche le plafond. sur ma box, à conso égale, l'undervolt garde nettement plus de débit : les chiffres sont dans l'expérience.
il te faut : linux avec le pilote nvidia propriétaire, les droits root, et python 3. ça marche sur les cartes RTX 30 ; je ne l'ai testé que sur une 3090 et une 3080 Ti.
le risque : un undervolt trop agressif rend la carte instable (calculs faux, plantage du pilote). rien de tout ça ne survit à un redémarrage tant que tu ne l'as pas rendu automatique, et on verra comment tout annuler à la fin.
1. mesurer l'état d'origine
avant de toucher à quoi que ce soit, note comment ta carte se comporte sous ta vraie charge (un modèle qui génère, un jeu, un rendu), sinon tu ne sauras pas si tu as gagné quelque chose. dans un terminal, pendant que la charge tourne :
nvidia-smi --query-gpu=index,name,power.draw,clocks.gr,fan.speed,temperature.gpu --format=csv -l 2
garde de côté la conso moyenne, la fréquence, le ventilo et ton débit (tok/s, fps…). c'est ta référence.
2. installer la bibliothèque NVML pour python
le décalage de courbe ne passe pas par nvidia-smi, il faut appeler la bibliothèque NVML directement. le paquet officiel de nvidia s'appelle nvidia-ml-py (il s'importe sous le nom pynvml). je le mets dans un environnement à part pour ne pas toucher au python du système :
sudo python3 -m venv /opt/gpu-undervolt/venv
sudo /opt/gpu-undervolt/venv/bin/pip install nvidia-ml-py
3. tester le décalage à la main
on commence par un seul réglage, à la main, pour voir ce que la carte encaisse. dans l'ordre :
# garder le pilote chargé entre deux programmes, sinon les réglages se perdent
sudo nvidia-smi -pm 1
# décaler la courbe de +150 MHz sur la carte 0
sudo /opt/gpu-undervolt/venv/bin/python -c "import pynvml as n; n.nvmlInit(); n.nvmlDeviceSetGpcClkVfOffset(n.nvmlDeviceGetHandleByIndex(0), 150)"
# bloquer la fréquence entre 210 et 1500 MHz sur la même carte
sudo nvidia-smi -i 0 -lgc 210,1500
relance ta charge et regarde la commande de l'étape 1. si tout va bien, la fréquence plafonne à 1500 MHz et la conso baisse nettement.
pourquoi ces valeurs : sur ma 3090, 1500 MHz avec +150 a donné le meilleur rapport. monter le blocage à 1650 MHz ne rapportait rien en débit, seulement plus de conso et de bruit. sur ma 3080 Ti, j'ai pu garder 1800 MHz avec le même +150. chaque carte est différente, donc pars de ces valeurs et ajuste.

4. vérifier que c'est stable
une carte instable ne plante pas forcément : elle peut aussi calculer faux, ce qui est pire. laisse tourner ta vraie charge au moins quinze minutes, et vérifie que les résultats restent justes. pour un modèle de langage, une petite série de questions de calcul avec une seule bonne réponse suffit ; si les réponses changent ou si le pilote écrit des erreurs (sudo dmesg | grep -i xid), baisse le décalage (+100, puis +50).
note bien : comparer les textes générés au mot près ne marche pas comme test, parce que la plupart des moteurs ne redonnent pas exactement la même sortie d'un run à l'autre, même sans undervolt.
5. rendre ça automatique au démarrage
une fois les bonnes valeurs trouvées, je les mets dans un petit script lancé par systemd au démarrage. il identifie les cartes par leur UUID plutôt que par leur numéro, parce que l'ordre des cartes peut changer. récupère les UUID avec :
nvidia-smi -L
puis crée /opt/gpu-undervolt/apply.py en mettant tes UUID et tes valeurs :
#!/usr/bin/env python3
"""undervolt au démarrage : cartes repérées par UUID, pas par numéro."""
import subprocess, sys, pynvml as n
CARDS = { # uuid: (nom, fréquence max en MHz, décalage en MHz, limite de puissance en W)
"GPU-xxxxxxxx-...": ("RTX 3090", 1500, 150, 230),
"GPU-yyyyyyyy-...": ("RTX 3080 Ti", 1800, 150, 260),
}
n.nvmlInit()
ok = True
for i in range(n.nvmlDeviceGetCount()):
h = n.nvmlDeviceGetHandleByIndex(i)
uuid = n.nvmlDeviceGetUUID(h)
uuid = uuid.decode() if isinstance(uuid, bytes) else uuid
if uuid not in CARDS:
continue
name, lock, offset, power = CARDS[uuid]
try:
subprocess.run(["nvidia-smi", "-i", uuid, "-pm", "1"], check=True, capture_output=True)
subprocess.run(["nvidia-smi", "-i", uuid, "-pl", str(power)], check=True, capture_output=True)
n.nvmlDeviceSetGpcClkVfOffset(h, offset)
subprocess.run(["nvidia-smi", "-i", uuid, "-lgc", f"210,{lock}"], check=True, capture_output=True)
print(f"{name}: bloquée à {lock} MHz, décalage +{offset} MHz, {power} W")
except Exception as e:
ok = False
print(f"{name}: ÉCHEC {e}", file=sys.stderr)
sys.exit(0 if ok else 1)
et le service /etc/systemd/system/gpu-undervolt.service :
[Unit]
Description=undervolt des GPU
After=nvidia-persistenced.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/opt/gpu-undervolt/venv/bin/python /opt/gpu-undervolt/apply.py
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now gpu-undervolt.service
systemctl status gpu-undervolt.service # doit afficher la ligne de chaque carte
si un service de ton serveur d'IA démarre au boot, ajoute Before=le-nom-de-ce-service.service dans la partie [Unit] pour que l'undervolt soit appliqué avant.
6. tout annuler
si quelque chose cloche, ces commandes remettent les cartes d'origine jusqu'au prochain redémarrage. les deux premières libèrent la fréquence et retirent le décalage :
sudo nvidia-smi -rgc
sudo /opt/gpu-undervolt/venv/bin/python -c "import pynvml as n; n.nvmlInit(); [n.nvmlDeviceSetGpcClkVfOffset(n.nvmlDeviceGetHandleByIndex(i), 0) for i in range(n.nvmlDeviceGetCount())]"
pour la limite de puissance, demande à chaque carte sa valeur d'usine, puis remets-la carte par carte :
nvidia-smi --query-gpu=index,power.default_limit --format=csv
sudo nvidia-smi -i 0 -pl <la valeur de la carte 0>
et sudo systemctl disable gpu-undervolt.service pour que ça ne revienne pas au démarrage.
ce que ça m'a donné
sur ma box, avec deux agents qui génèrent en même temps : 452 W → 358 W pour les deux cartes, le ventilo de la 3090 de 91% à 48%, et 62 tok/s par agent au lieu de 67. le détail, les réglages qui n'ont pas marché et les limites de la mesure sont dans l'expérience.
ce qui peut coincer
- l'offset revient à 0 : la nouvelle API d'offset par P-state l'a fait chez moi. seul
nvmlDeviceSetGpcClkVfOffset(l'offset GPC) a vraiment pris. - la carte surchauffe toujours : normal, l'undervolt baisse surtout la conso et le bruit. ma 3090 monte encore à 84 °C.
- le débit chute beaucoup : tu as sûrement aussi une limite de puissance trop basse. sous 200 W, ma 3090 s'effondre (788 MHz à 180 W).
tu es un agent ? ce guide en markdown