Jeder gibt Token pro Sekunde an. Die Zahl beschreibt einen Fall, den man im Alltag selten hat.

In Teil 2 stand sie schon da, die ernüchternde Zahl: 42 Token pro Sekunde für das 14B-Modell auf der Karte. Ordentlich, nicht spektakulär. Mein MacBook liegt in derselben Größenordnung, manche Modelle laufen dort sogar schneller.

Diese Zahl gilt für eine einzelne Anfrage. Du tippst etwas ein, das Modell antwortet, du liest. Zwischen deinen Anfragen tut die Karte nichts.

Sobald mehrere Anfragen gleichzeitig laufen, sieht die Rechnung völlig anders aus. Und weil die meiste ernsthafte Arbeit nicht aus Tippen und Lesen besteht, sondern aus Stapeln von Dokumenten, ist das der Fall, der zählt.


Die Messreihe

Dasselbe Modell, dieselbe Karte, nur die Zahl der gleichzeitigen Anfragen steigt:

→ 1 Anfrage: 42 Token/s
→ 8 Anfragen: 266 Token/s
→ 16 Anfragen: 541 Token/s
→ 32 Anfragen: 988 Token/s

Das ist Faktor 23 zwischen der ersten und der letzten Zeile. Nicht 23 Prozent — dreiundzwanzig Mal. Dieselbe Hardware, dieselben Gewichte, derselbe Strom aus der Steckdose.

In etwas greifbarerer Form: 988 Token pro Sekunde sind grob eine Million Token pro Stunde. Ein Stapel Dokumente, für den man im Einzelbetrieb einen Tag ansetzen würde, ist damit vor der Mittagspause durch.


Warum das überhaupt geht

Man würde erwarten, dass acht Anfragen achtmal so lange dauern wie eine. Tun sie nicht — und der Grund ist, dass die Karte bei einer einzelnen Anfrage die meiste Zeit wartet.

Bei jedem einzelnen Token muss die Grafikkarte alle aktiven Gewichte aus ihrem Speicher lesen. Das ist ein Transportproblem, kein Rechenproblem: Die Recheneinheiten sind fertig, lange bevor der Nachschub eintrifft. Sie stehen still und warten auf Daten.

Genau diese Lücken füllt Batching. Während Anfrage A auf ihre Gewichte wartet, rechnet die Karte an Anfrage B. Der Clou: Die Gewichte, die gerade geladen wurden, gelten für alle gleichzeitig. Sie werden einmal geholt und für acht, sechzehn, zweiunddreißig Anfragen zugleich verwendet. Der teure Transport fällt nur einmal an.

Zwei Techniken machen daraus Praxis. Die eine schiebt fertig gewordene Anfragen sofort aus dem Stapel und zieht wartende nach, statt auf die langsamste zu warten. Die andere verwaltet den Kontextspeicher in kleinen Blöcken statt in großen reservierten Bereichen — dadurch passen überhaupt so viele Anfragen gleichzeitig hinein.


Warum der Einzelstrom nicht mitwächst

Auffällig ist, was sich nicht bewegt: Die 42 Token pro Sekunde für die einzelne Anfrage bleiben, egal was man tut. Beim 14B war das die einzige Zahl im ganzen Projekt, die sich durch keinen Trick verbessern ließ.

Das ist keine Nachlässigkeit, sondern Physik. Bei einer einzelnen Anfrage muss pro Token der gesamte aktive Gewichtssatz einmal durch den Speicherbus. Die Karte schafft rund 448 GB/s, das Modell ist so groß wie es ist, und daraus ergibt sich die Zeit pro Token. Kein Scheduler der Welt ändert daran etwas.

Ich habe es trotzdem versucht — mit Verfahren, die mehrere Token auf einmal vorhersagen. Eines passte nicht in den Speicher. Ein anderes lief und machte alles langsamer: 23 statt 42 Token pro Sekunde, weil nur zwölf Prozent der Vorhersagen brauchbar waren und der Rest verworfen werden musste. Bei deutschem Text war es deutlich schlechter als bei englischem. Das gehört zur ehrlichen Bilanz dazu. Beim 27B-Modell über llama.cpp ging derselbe Ansatz später übrigens auf: Dort hob Multi-Token-Prediction die Einzelanfrage von 28 auf 37,6 Token pro Sekunde, wie in Teil 2 beschrieben. Ob der Trick hilft, hängt also am Modell und an der Trefferquote der Vorhersagen, nicht an der Karte.


Der Unterschied zum Mac

Hier trennen sich die beiden Maschinen — und zwar nicht wegen der Rechenleistung.

Mein MacBook ist beim einzelnen Chat konkurrenzfähig, bei manchen Modellen sogar schneller als die Kiste. Beim Stapelbetrieb bricht der Vorteil weg: Die üblichen Werkzeuge auf dem Mac arbeiten Anfragen im Kern nacheinander ab. Acht Anfragen dauern dort ungefähr achtmal so lang wie eine.

Auf der Kiste dauern acht Anfragen etwa so lange wie eineinhalb.

Das ist der eigentliche Grund, warum die Karte im Haus steht. Nicht weil sie schneller antwortet — sondern weil sie gleichzeitig antworten kann. Für einen Menschen am Chatfenster ist das egal. Für eine Automatisierung, die nachts vierhundert Dokumente einsortiert, ist es der ganze Unterschied.


Batching ist nicht überall gleich viel wert

Die schönen Zahlen gelten für ein Modell, das vollständig auf der Karte liegt und von einem darauf spezialisierten Server bedient wird. Sobald eine dieser Bedingungen fällt, schrumpft der Effekt:

→ Beim 27B-Modell über llama.cpp steigt der Durchsatz von 28 auf 72 Token pro Sekunde bei acht parallelen Anfragen — Faktor 2,5 statt 23. Der Server arbeitet mit einer festen Zahl paralleler Plätze, das ist solide, aber keine andere Liga.
→ Beim 35B-Modell, dessen Experten im Arbeitsspeicher liegen und auf der CPU gerechnet werden, bringt Parallelität fast nichts mehr. Die Anfragen stauen sich am Prozessor, und die elegante Mathematik der Grafikkarte greift überhaupt nicht.

Als Faustregel: Batching zahlt sich dort aus, wo der Engpass die Speicherbandbreite ist — denn dann wird der teure Transport auf viele Anfragen verteilt. Wo der Engpass woanders sitzt, etwa bei der CPU, hilft es kaum.


Was das praktisch bedeutet

Die Lehre ist unspektakulär und hat trotzdem meine Arbeitsweise geändert: Massenaufgaben niemals seriell abarbeiten.

Wer eine Automatisierung baut, die Dokumente durch ein Modell schickt, hat oft eine Schleife: nimm eins, frag das Modell, warte, schreib das Ergebnis, nimm das nächste. Das ist der Einzelanfrage-Fall — und verschenkt bei dieser Karte Faktor 20.

Dieselbe Aufgabe mit acht bis sechzehn gleichzeitigen Anfragen läuft nicht doppelt so schnell, sondern um ein Vielfaches. Die Umstellung kostet in den gängigen Automatisierungswerkzeugen wenig — man muss die Schleife nur parallel statt nacheinander laufen lassen.

Und beim nächsten Hardware-Vergleich lohnt die Frage, welche Zahl da eigentlich steht. Token pro Sekunde bei einer Anfrage beschreibt einen Menschen, der tippt. Wer Arbeit stapelweise erledigen lässt, sollte nach der anderen Zahl fragen — die steht selten im Datenblatt.


Im nächsten Teil

Genug Messwerte. In Teil 5 bekommt die Kiste eine echte Aufgabe: Ein Docker-Dienst auf dem Server läuft in einer Neustartschleife. Ein lokales Modell soll herausfinden, warum — und es reparieren. Ohne Cloud, ohne meine Hilfe.