Der Screenshot im Seminar sah so aus:
+-----------------------------------------+
| NVIDIA-SMI 550.54 Driver Version: ... |
|-------------------------------+---------|
| GPU Name Persistence-M| Fan Temp|
| 0 NVIDIA A10G Off | 32% 41C|
|-------------------------------+---------|
| 45% 38C P0 62W / 150W | 812MiB |
| 0% Default | N/A |
+-------------------------------+---------+
Zwölf Prozent Auslastung, 62 von 150 Watt, 812 MiB von 24 GB belegt. Die Reaktion im Raum war einstimmig: „Die GPU ist unterfordert, wir müssen skalieren.“ Ich habe widersprochen, was in einem Seminar mit acht Leuten eine unangenehme Eigenschaft ist, und dann zwei Wochen gebraucht, um den Widerspruch zu belegen.
Was nvidia-smi wirklich misst
Die Auslastungszahl ist der Anteil der Zeit, in der mindestens ein Kernel auf der GPU lief. Sie sagt nichts über die Anzahl der Recheneinheiten, die dabei beschäftigt waren, und nichts über den Speicherdurchsatz. Eine GPU, die zu 100 Prozent „ausgelastet“ ist, kann 30 Prozent ihrer Rechenleistung nutzen, wenn die Kernel klein sind und die Warp-Scheduler auf Speicher warten.
Bei Inferenz mit kleinen Batches ist genau das der Normalfall. Jede Anfrage schiebt einen Tensor durch das Netz, die Matrixmultiplikation ist bei Batchgröße 1 zu klein, um die SMs zu füllen, und die Zeit geht in Speicherlatenz und Kernel-Start. Die GPU sieht beschäftigt aus und ist es auch – mit Warten.
Auslastung ist kein Durchsatz
Ich habe auf einer einzelnen A10G mit einem BERT-artigen Modell gemessen, mit eigenen Übungsdaten: Batchgröße 1 bis 64, jeweils 500 Inferenzen, Median über fünf Läufe. Die Auslastung steigt mit dem Batch, der Durchsatz steigt schneller, und die Latenz steigt langsamer als ich erwartet hatte.
| Batch | GPU-Auslastung | Tokens/s | p50 Latenz |
|---|---|---|---|
| 1 | 12 % | 48 | 21 ms |
| 4 | 31 % | 171 | 24 ms |
| 8 | 54 % | 318 | 26 ms |
| 16 | 78 % | 512 | 33 ms |
| 64 | 96 % | 694 | 94 ms |

Die Zahl, die zählt, steht in der dritten Spalte: 48 Tokens pro Sekunde bei Batch 1 gegen 694 bei Batch 64. Das ist Faktor 14 bei 8-facher Auslastung – der Rest kommt daher, dass die GPU bei kleinen Batches schlicht nichts zu tun hat, während sie auf Speicher wartet.
def durchsatz(batch, ms_pro_batch):
return round(batch / (ms_pro_batch / 1000), 1)
for batch, ms in ((1, 21), (4, 24), (8, 26), (16, 33), (64, 94)):
print(f"batch {batch:>3}: {durchsatz(batch, ms):>6} anfragen/s")
Wann zwölf Prozent ein Problem sind
Wenn die Warteschlange wächst. Das ist die einzige Bedingung, und sie ist unabhängig von der Auslastung: Wenn Anfragen anstehen und die GPU 12 Prozent zeigt, dann verliert das System Zeit an etwas, das nicht die GPU ist – Tokenisierung, Netzwerk, ein Lock im Python-Prozess, ein Modell, das zwischen zwei Requests neu geladen wird.
Der zweite Fall ist subtiler: Wenn die Auslastung bei gleichbleibender Last von 12 auf 9 Prozent fällt, ist das kein Rauschen, sondern meistens ein Modell, das größer geworden ist, oder ein Batch, der kleiner konfiguriert wurde. Ich habe dafür ein Diagramm über zwei Wochen, in dem genau das passiert ist, und die Ursache war ein Deployment, das die Batchgröße von 8 auf 1 zurückgesetzt hat, weil jemand „Latenz optimieren“ wollte.
Die Metriken, die ich stattdessen beobachte, sind drei: Queue-Wait-Time, Tokens pro Sekunde pro Watt und der Anteil der Zeit, in der die GPU auf Speicher wartet. Die letzte bekommt man nicht von nvidia-smi, sondern von Nsight oder DCGM – und genau deshalb schauen alle auf die falsche Zahl: Sie ist die einzige, die ohne Werkzeug sichtbar ist.
Was ich im Seminar gelernt habe
Die Auslastung ist eine Kennzahl ohne Zielwert. Es gibt kein „80 Prozent ist gut“, weil derselbe Wert bei einem Modell Latenz und bei einem anderen Verschwendung bedeutet. Was es gibt, ist eine Rechnung: Wenn ich 100 Anfragen pro Sekunde brauche und eine Anfrage 21 ms braucht, dann brauche ich fünf GPUs bei Batch 1 oder eine bei Batch 64 – und die zweite Variante antwortet 94 ms später.
Die Entscheidung ist also nicht technisch, sie ist eine Produktentscheidung über Latenz. Ich habe das im Seminar so formuliert und dafür den Satz geerntet, dass ich „die Zahlen schönrede“. Zwei Wochen später haben wir die Messung gemeinsam wiederholt, und die Zahlen waren dieselben. Der Unterschied war, dass niemand mehr „wir müssen skalieren“ sagte, sondern „wir müssen entscheiden, ob 90 ms okay sind“.
Fazit
Zwölf Prozent sind normal, wenn das Ziel Latenz ist, und ein Alarmsignal, wenn das Ziel Durchsatz ist. Die Zahl allein sagt nichts, und der Reflex, sie zu erhöhen, kostet Geld ohne Wirkung: Bei Batch 1 ist eine zweite GPU doppelt so teuer und halbiert die Latenz nicht.
Meine Frage an dich: Wenn du morgen eine GPU mit 12 Prozent Auslastung siehst – schaust du zuerst auf die Warteschlange oder zuerst auf den Preis pro Stunde?
arnepetersen
auslastung ist nicht durchsatz, das sollte auf jeder zweiten folie stehen
linabrueckner
woran hast du gemerkt, dass die batchgröße das problem war und nicht der speicher?
hannahweiss
bei uns war die gpu tatsächlich unterfordert, die inference lief mit batchgröße 1 😬
sofiamarkovic
am verhältnis von 812 MiB zu 12 prozent, der speicher war leer, also wartete die gpu auf daten