SSD Nodes Learn Hosting plans →
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-08-25

Warum Ihr LLM bei 5 Benutzern stockt

Ein Benutzer ist schnell, fünf warten? Ollama verarbeitet standardmäßig nur 1 Anfrage parallel. Erfahren Sie, wie Batching, KV-Cache, Prefill und Warteschlangen die Kapazität begrenzen.

Warum wird ein selbst gehostetes LLM langsamer, wenn mehr Benutzer hinzukommen?

Ein selbst gehostetes LLM kommt bei 5 gleichzeitigen Benutzern ins Stocken, weil der Server weiterhin jeweils nur eine Antwort generiert und die anderen vier Anfragen in einer Warteschlange stehen. In der Ollama-Dokumentation ist der Standardwert eindeutig beschrieben: OLLAMA_NUM_PARALLEL ist „the maximum number of parallel requests each model will process at the same time, default 1“. Es ist nichts defekt. Vier von fünf Personen warten lediglich, bis sie an der Reihe sind.

Die Lösung ist nur selten ein größerer Server. Benötigt wird eine Inference-Engine, die viele Anfragen im selben Forward Pass durch das Modell verarbeitet, sowie ausreichend freier Speicher, um währenddessen die Konversationen aller Benutzer zu halten. Beide Aspekte sind wichtig. Der zweite bestimmt tatsächlich Ihre Obergrenze.

Die beiden Phasen jeder Anfrage

Prefill liest den gesamten Prompt auf einmal und baut dafür den Attention-Cache auf. Jeder Prompt-Token durchläuft das Modell gemeinsam mit den anderen Tokens. Deshalb ist Prefill eine große Matrixmultiplikation und wird durch den Rechendurchsatz begrenzt. Decode erzeugt die Antwort anschließend jeweils für einen Token. Für jeden Token müssen die vollständigen Gewichte des Modells erneut aus dem Speicher gelesen werden, während die für diesen einzelnen Token ausgeführten Berechnungen gering sind. Decode wird durch die Speicherbandbreite begrenzt.

Diese Asymmetrie ist der eigentliche Grund, warum Batching funktioniert. Beim Decodieren für einen Benutzer werden beispielsweise pro Token 5 GB an Gewichten gelesen, während die meisten Recheneinheiten ungenutzt bleiben. Kommt eine zweite Anfrage hinzu, liest die Engine dieselben 5 GB einmal und berechnet anschließend daraus zwei Tokens. Der zweite Benutzer verursacht dadurch kaum zusätzliche Laufzeit. Wenn Anfragen strikt nacheinander verarbeitet werden, geht dieser Vorteil verloren.

Zwei Kennzahlen bestimmen, wie ein Benutzer die Leistung wahrnimmt. TTFT (time to first token) ist die Wartezeit in der Warteschlange plus Prefill. ITL (inter-token latency) ist der Abstand zwischen den gestreamten Tokens und wird durch Decode bestimmt. Ein langsamer Server ist meist bei einer dieser Kennzahlen langsam, und die erforderlichen Anpassungen sind nicht identisch. Sie sollten daher zunächst feststellen, gegen welche dieser beiden Größen Sie ankämpfen, bevor Sie Einstellungen ändern. Prefill und Decode getrennt messen zeigt Ihnen, welche davon betroffen ist.

Statisches Batching lässt alle auf die langsamste Antwort warten

Statisches Batching ist die naive Variante. Sie erhalten es, wenn Sie Anfragen selbst im Anwendungscode gruppieren. Die Engine sammelt N Anfragen, verarbeitet sie gemeinsam und hält jeden Slot belegt, bis die längste Generierung in der Gruppe abgeschlossen ist.

Ein Benutzer, der eine Zusammenfassung mit 1,200 Tokens anfordert, hält vier einzeilige Antworten im Batch fest, weil der Batch keinen Slot freigibt, bevor sein langsamstes Element abgeschlossen ist.

Daraus ergeben sich zwei Nachteile. Abgeschlossene Sequenzen belegen weiterhin Slots, obwohl sie keine nützliche Rechenarbeit mehr ausführen. Dadurch sinkt der effektive Durchsatz, wenn die Ausgabelängen variieren. Bei Chat-Anfragen unterscheiden sich die Ausgabelängen häufig stark. Eine Anfrage, die einen Schritt nach der Bildung des Batch eintrifft, wartet, bis der gesamte Batch abgearbeitet ist, bevor ihr Prefill überhaupt beginnt. Dadurch wird ihr TTFT durch den Essay eines anderen Benutzers bestimmt.

Continuous Batching nimmt bei jedem Token Anfragen an und entfernt sie

Continuous Batching plant auf Ebene eines einzelnen Decoding-Schritts. Nach jedem Schritt entfernt der Scheduler Sequenzen, die gerade ihr Stop-Token ausgegeben haben, und nimmt wartende Anfragen in die freien Slots auf. Eine Antwort, die bei Schritt 40 endet, gibt ihren Slot bei Schritt 40 frei, nicht erst am Ende eines Batches.

Das ist kein exotisches Verfahren. llama-server dokumentiert -cb, --cont-batching als „whether to enable continuous batching (a.k.a dynamic batching) (default: enabled)“, und vLLM basiert auf diesem Konzept. Auch Ollama verarbeitet parallele Anfragen. Der Standardwert begrenzt die Anzahl lediglich auf eins. Deshalb schließen viele Nutzer, dass ihre Hardware keine Parallelität unterstützt, obwohl ihre Konfiguration dies verhindert.

Veröffentlichte Ergebnisse zu Continuous Batching werden meist auf Rechenzentrumskarten gemessen, die sowohl freie Rechenkapazität als auch mehrere Dutzend Gigabyte für den Cache haben. Die Form dieser Ergebnisse lässt sich auf Ihr System übertragen. Ihre Größenordnung jedoch nicht. Der folgende Abschnitt zum Speicher erklärt den Grund.

Prefill konkurriert mit Decode um dieselben Rechenressourcen

Wenn eine neue Anfrage eingeht, während vier Antworten gestreamt werden, muss ihr Prompt zuerst vorverarbeitet werden. Prefill ist rechenintensiv. Gibt der Scheduler diesem Prefill einen eigenen Schritt, erhalten die vier Nutzer währenddessen kein Token. Bei einem langen Prompt ist das in jedem geöffneten Fenster als sichtbare Pause bemerkbar. Das ist das Stottern, das gemeint ist, wenn der Server jedes Mal kurz stockt, sobald jemand anderes auf „Senden“ klickt.

Chunked Prefill teilt einen langen Prompt in Abschnitte auf und verarbeitet jeden Abschnitt im selben Schritt wie die laufenden Decodes. Der Tuning-Leitfaden von vLLM beschreibt den Zielkonflikt direkt: Kleinere Chunk-Budgets „achieve better ITL because there are fewer prefills slowing down decodes“, während höhere Werte „achieve better time to first token (TTFT) as you can process more prefill tokens in a batch“. Sie entscheiden, wessen Nutzungserlebnis geschützt werden soll: das der Person, die auf den Beginn einer Antwort wartet, oder das der Personen, die den Text beim Streamen beobachten.

Die Prompt-Länge bestimmt, wie stark sich dies auswirkt. Ein Prompt mit 6,000 Token und einer Antwort mit 200 Token verursacht 6,000 Token Prefill-Arbeit gegenüber 200 Decode-Schritten. Retrieval-augmented Chat und lange System-Prompts führen beide in diesen Bereich. Prefill ist dann kein vernachlässigbarer Anteil mehr, sondern der Vorgang, auf den die Nutzer warten. Prefix-Caching hilft, wenn sich der lange Teil wiederholt: vLLM stellt --enable-prefix-caching bereit. Damit wird der Cache für ein gemeinsames Prompt-Präfix wiederverwendet, anstatt es für jede Anfrage neu zu berechnen.

Der KV-Cache läuft zuerst voll

Jedes Token in jeder aktiven Konversation hinterlegt in jeder Modellschicht einen Key-Vektor und einen Value-Vektor. Das ist der KV-Cache (Key/Value-Cache). Er verhindert, dass beim Generieren jedes neuen Tokens der gesamte Prompt erneut berechnet werden muss. Seine Größe pro Token wird durch die Modellstruktur festgelegt: 2 (ein Key und ein Value) mal die Anzahl der Schichten, mal die Anzahl der Key/Value-Heads, mal die Head-Dimension, mal die Byte-Anzahl pro Wert. Lesen Sie diese Werte aus dem config.json des Modells ab.

Wenn Sie die Berechnung einmal durchführen, ist die Obergrenze nicht mehr rätselhaft. Ein typisches 8B-Modell mit 36 Schichten, 8 Key/Value-Heads und einer Head-Dimension von 128 benötigt bei einem Cache in 16 Bit pro Token 2 36 8 128 2 Byte. Das entspricht 147,456 Byte oder etwa 144 KiB. Eine Konversation mit 8,192 Tokens benötigt daher ungefähr 1.2 GB Cache. Fünf solcher Konversationen benötigen zusätzlich zu den Gewichten ungefähr 6 GB. Das ist die entscheidende Antwort auf die Frage, wie viele Benutzer gleichzeitig unterstützt werden.

Parallelität vervielfacht den Kontext. Die Werkzeuge weisen ausdrücklich darauf hin. In der Ollama-FAQ heißt es: "Die parallele Verarbeitung von Anfragen für ein bestimmtes Modell erhöht die Kontextgröße um die Anzahl der parallelen Anfragen. Ein Kontext von 2K mit 4 parallelen Anfragen führt beispielsweise zu einem Kontext von 8K und zusätzlicher Speicherzuweisung." Der benötigte Arbeitsspeicher skaliert mit OLLAMA_NUM_PARALLEL multipliziert mit OLLAMA_CONTEXT_LENGTH. In llama-server wird der mit -c angeforderte Kontext auf die -np Slots verteilt. Wenn Sie nur die Anzahl der Slots erhöhen, verringert sich daher die Kapazität jeder einzelnen Anfrage. Lesen Sie den Kontext pro Slot aus dem Startprotokoll ab, statt ihn anzunehmen.

vLLM reserviert den Speicher stattdessen vorab. --gpu-memory-utilization (Standardwert 0.92) ist "der Anteil des GPU-Speichers, der für den Model Executor verwendet werden soll". Der nach den Gewichten verbleibende Speicher wird zum paginierten KV-Pool. Wenn dieser Pool nicht mehr ausreicht, entfernt der Scheduler eine Anfrage, statt mit einem Fehler abzubrechen:

WARNING 05-09 00:49:33 scheduler.py:1057] Sequence group 0 is preempted by PreemptionMode.RECOMPUTE mode because there is not enough KV cache space.

In der V1-Engine von vLLM ist RECOMPUTE der Standardmodus für die Vorabentfernung. Eine entfernte Anfrage verwirft dabei ihren Cache und führt beim erneuten Einplanen den Prefill erneut aus. Diese Arbeit wird zweimal ausgeführt. Die Dokumentation warnt, dass "Vorabentfernung und Neuberechnung die Ende-zu-Ende-Latenz beeinträchtigen können". Diese Protokollzeile erklärt am besten, warum ein einzelner Benutzer deutlich länger warten musste als alle anderen, obwohl der Durchschnittswert unauffällig war. Setzen Sie disable_log_stats=False, um den kumulierten Zähler zu protokollieren, oder lesen Sie den Vorabentfernungszähler aus den von vLLM bereitgestellten Prometheus-Metriken ab.

Änderungen bei 2, 5 und 20 gleichzeitig aktiven Benutzern

Zwei Benutzer. Auf einer GPU mit ausreichendem Cache ist die zusätzliche Last nahezu nicht wahrnehmbar, weil der zweite Decodierungsstream den ersten mit sehr geringem Mehraufwand begleitet. Auf einer CPU-only-VPS mit 4 bis 8 GB RAM ist sie dagegen nicht kostenlos: Beide Streams teilen sich dieselben wenigen vCPUs und dieselbe RAM-Bandbreite. Daher sieht jeder Benutzer ungefähr halb so viele Tokens pro Sekunde, und der Cache-Bedarf verdoppelt sich bei einem deutlich kleineren verfügbaren Budget.

Fünf Benutzer. Ab hier reichen die Standardwerte nicht mehr aus. Zunächst entsteht ein Warteschlangenproblem. Bei OLLAMA_NUM_PARALLEL auf 1 warten vier Personen auf diejenige, die die lange Antwort angefordert hat. Sobald sie an der Reihe sind, sehen sie jeweils die normale Geschwindigkeit. Erhöhen Sie die Anzahl der parallelen Verarbeitungen, verändert sich das Problem: Fünf Slots mit jeweils 8K Kontext benötigen einen Cache für 40K Tokens. Passt dieser nicht in den VRAM, lagert die Engine Layer in den System-RAM aus. Passt er auch dort nicht hinein, verwendet das System Swap, und die Anzahl der Tokens pro Sekunde bricht ein.

Zwanzig Benutzer. Zwanzig Menschen in einer Chat-Oberfläche bedeuten normalerweise nicht zwanzig gleichzeitig aktive Anfragen. Das ist der wichtigste Punkt, den Sie vor dem Kauf der Hardware verstehen sollten. Eine Person liest eine Antwort und wartet zwischen den Eingaben 20 bis 60 Sekunden. Der größte Teil ihrer Sitzung ist daher inaktiv. Zwanzig Agenten oder zwanzig Aufgaben zur Dokumentzusammenfassung erzeugen dagegen zwanzig echte Streams ohne Leerlauf. Dafür ist eine andere Maschine erforderlich. Ein Entwickler, der einen Coding-Agent auf seinen eigenen Ollama-Server angesetzt hat, liegt näher am zweiten Fall als am ersten. Der Agent sendet so lange weitere Anfragen, wie die Aufgabe läuft, und lässt die Lesepausen eines Menschen vollständig aus.

Sind Ihre Benutzer gleichzeitig aktiv oder nur angemeldet?

Ermitteln Sie die Anzahl gleichzeitig laufender Anfragen, bevor Sie die Größe festlegen. Die Berechnung ist einfach: Gleichzeitig laufende Anfragen entsprechen der Benutzerzahl mal der für die Generierung pro Durchlauf benötigten Zeit, geteilt durch die Zeit zwischen den Durchläufen.

  1. Messen Sie zuerst Ihre Geschwindigkeit für einen einzelnen Datenstrom, sowohl beim Prefill als auch beim Decoding. Übernehmen Sie keinen Wert von der Grafikkarte einer anderen Person: Messen Sie Tokens pro Sekunde auf Ihrem eigenen System und verwenden Sie den ermittelten Wert.
  2. Schätzen Sie den Auslastungszyklus. 20 Chat-Benutzer, 12 Sekunden Generierungszeit pro Durchlauf und ein Durchlauf alle 90 Sekunden ergeben 20 * 12 / 90, also etwa 2.7 gleichzeitig laufende Anfragen.
  3. Setzen Sie die Anzahl der Slots etwas höher an und prüfen Sie sie anschließend anhand des Speichers: Die Anzahl der Slots mal dem Kontext pro Anfrage muss in die tatsächlich verfügbaren Cache-Tokens passen.
  4. Halten Sie die Warteschlange kurz, damit überzählige Anfragen schnell und eindeutig fehlschlagen.

Die verfügbaren Cache-Tokens entsprechen dem freien Speicher nach Abzug der Gewichte, geteilt durch den im vorherigen Abschnitt genannten Kosten pro Token. Eine 24-GB-Grafikkarte, auf der ein 8B-Modell mit 16-bit ausgeführt wird, verwendet etwa 16 GB für die Gewichte und hat bei der standardmäßigen Auslastung ungefähr 6 GB nutzbaren Cache. Das reicht für etwa fünf Unterhaltungen mit 8K. Um mehr Unterhaltungen unterzubringen, verkürzen Sie den Kontext pro Anfrage oder speichern Sie den Cache mit 8-bit (llama-server benötigt --cache-type-k q8_0). Beides erhöht die Gleichzeitigkeit, indem an anderer Stelle etwas aufgegeben wird. Lesen Sie sich die konkreten Nachteile dieses Kompromisses durch, bevor Sie Geld in Hardware investieren: wann sich ein GPU-VPS gegenüber API-Tokens amortisiert.

Wenn Ollamas Standardwerte nicht mehr ausreichen

Erhöhen Sie die Anzahl der parallelen Anfragen über die Service-Unit, weil ein Export in der Shell einen von systemd verwalteten Daemon nicht erreicht.

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_CONTEXT_LENGTH=8192"
Environment="OLLAMA_MAX_QUEUE=64"
sudo systemctl daemon-reload
sudo systemctl restart ollama
systemctl show ollama --property=Environment
ollama ps

systemctl show sollte die drei Variablen ausgeben, die Sie gerade gesetzt haben. Falls das nicht geschieht, wurde das Drop-in nicht gespeichert, und alle weiteren Schritte bleiben wirkungslos. ollama ps listet anschließend das geladene Modell mit einer Größe auf, die über die reinen Gewichte hinausgeht, weil vier Slots mit jeweils 8,192 Tokens zusätzlich 32,768 Tokens Cache reservieren. Eine PROCESSOR-Spalte, die einen Teil des Modells auf der CPU ausweist, obwohl Sie mit einem vollständigen Laden auf der GPU gerechnet haben, bedeutet, dass Sie mehr Cache angefordert haben, als auf der Karte noch verfügbar war. Verringern Sie eine der beiden Zahlen. Die Verringerung des Kontexts ist normalerweise die sicherere Option. Ein zu kleines Fenster schneidet lange Prompts jedoch stillschweigend ab, statt einen Fehler auszugeben. Daher sollten Sie num_ctx gezielt dimensionieren, statt den Wert so lange zu reduzieren, bis das Modell passt.

Der Standardwert für die Warteschlange verdient eine genauere Betrachtung. Ollama reiht bis zu OLLAMA_MAX_QUEUE Anfragen ein, und „der Standardwert ist 512“. Darüber hinaus antwortet es „mit einem 503-Fehler, der angibt, dass der Server überlastet ist“. Eine Warteschlange mit 512 Einträgen ist auf einem System, das vier Anfragen gleichzeitig verarbeitet, ein Versprechen, das Sie nicht einhalten können, weil der Client an Position 300 lange vor seinem Aufruf einen Timeout erreicht. Eine kurze Warteschlange gibt einen Fehler zurück, den Ihre Anwendung erneut versuchen oder melden kann. Das ist besser als ein Ladeindikator, der nie verschwindet.

Testen Sie die Einstellung unter realen Bedingungen. Senden Sie aus zwei Terminals gleichzeitig jeweils eine Anfrage und beobachten Sie beide. Wenn die zweite Anfrage erst dann eine Ausgabe erzeugt, wenn die erste abgeschlossen ist, wurde die Einstellung für parallele Anfragen nicht übernommen.

Wann sich eine echte Serving-Engine amortisiert

vLLM lohnt den zusätzlichen Einrichtungsaufwand, wenn Sie eine GPU mit Reserven haben und tatsächlich mehr als ungefähr vier Anfragen gleichzeitig verarbeitet werden. Der Scheduler arbeitet tokenweise, der Cache ist seitenweise organisiert, sodass freie Fragmente wiederverwendet werden, und ungenutzter VRAM wird für mehr Parallelität eingesetzt, statt ungenutzt zu bleiben. Im August 2026 bestehen die dokumentierte Installation und der Start aus zwei Befehlen:

uv pip install vllm --torch-backend=auto
vllm serve Qwen/Qwen2.5-1.5B-Instruct
curl http://localhost:8000/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "Qwen/Qwen2.5-1.5B-Instruct",
        "messages": [{"role": "user", "content": "Say hello."}]
    }'

Eine Antwort mit einem choices-Array bedeutet, dass der Server läuft und das Modell geladen ist. Unter Last sind die beiden wichtigen Stellschrauben --max-num-seqs, die „maximale Anzahl der Sequenzen, die in einer einzelnen Iteration verarbeitet werden“, und --max-num-batched-tokens, die „maximale Anzahl der Tokens, die in einer einzelnen Iteration verarbeitet werden“. Der erste Wert begrenzt die Parallelität. Der zweite Wert legt das zuvor beschriebene Budget für Chunked Prefill fest.

Bei weniger als ungefähr vier gleichzeitig laufenden Anfragen oder auf einem System ohne unterstützte GPU verursacht vLLM zusätzliche Komplexität und bietet wenig Nutzen. vLLM erwartet eine CUDA-Karte und beansprucht beim Start den größten Teil des Speichers. Auf einem VPS mit 4 bis 8 GB ist das der falsche Kompromiss. Dort ist ein kleineres Modell mit kürzerem Kontext und einer von Ihnen kontrollierten Warteschlange die bessere Lösung. wie sich Ollama und vLLM als Serving-Engines unterscheiden behandelt diese Auswahl vollständig, und Qwen 3 8B auf einem VPS ausführen zeigt, welche Anforderungen ein mittelgroßes Modell stellt, bevor Sie einen einzigen zusätzlichen Benutzer hinzufügen.

Der Zielkonflikt, den die gängige Überlieferung verschweigt

Continuous Batching erhöht den Gesamtdurchsatz und verbessert in der Regel auch die mediane Latenz, weil eine eingereihte Anfrage früher startet. Die Tail-Latenz entwickelt sich jedoch in die entgegengesetzte Richtung. Dieser Aspekt wird nur selten erwähnt.

Jede zusätzliche Sequenz in einem Schritt verursacht etwas mehr Arbeit. Deshalb steigt die ITL für alle, sobald sich der Batch füllt. Das Prefill einer neu eingegangenen Anfrage beansprucht einen Teil eines Schritts, der den bereits streamenden Benutzern sonst zur Verfügung gestanden hätte. Unter Cache-Druck führt der Scheduler eine Präemption durch. Dadurch wird eine teilweise generierte Anfrage an den Anfang ihres Prefills zurückgesetzt.

Eine Chat-Oberfläche macht die Tail-Latenzen sichtbar, nicht die Durchschnittswerte. Ein Stream, der mitten im Satz zwei Sekunden pausiert, wirkt fehlerhaft, selbst wenn die Gesamtzeit bis zum Abschluss gut ist. Messen Sie p95 TTFT und p95 ITL unter der erwarteten Last. Betrachten Sie die mittlere Tokenrate pro Sekunde als Kapazitätswert und nicht als Beschreibung der tatsächlichen Nutzungserfahrung.

Daraus ergibt sich die praktische Einstellung. Begrenzen Sie die Parallelität etwas unterhalb dessen, was der Speicher zulässt, damit die Engine nie eine Präemption durchführen muss. Eine kurze, vorhersehbare Warteschlange ist besser als ein tiefer Batch, der thrashing verursacht. Ein Benutzer, der vier Sekunden wartet und danach einen gleichmäßigen Stream erhält, ist zufriedener als ein Benutzer, dessen Stream sofort startet und anschließend zweimal stockt.

Was bei langsamer Verarbeitung zu prüfen ist

Jeder einzelne Benutzer ist unauffällig, aber die Wartezeit ist lang. Das ist eine Warteschlange, kein Geschwindigkeitsproblem. Prüfen Sie zuerst die Einstellung für die Parallelverarbeitung. Das Modell verarbeitet die Anfragen korrekt, jedoch eine nach der anderen.

HTTP 503 von Ollama. Die Warteschlange ist voll. Entweder ist der Server tatsächlich ausgelastet, oder OLLAMA_MAX_QUEUE ist absichtlich niedrig gesetzt, um die Last zu reduzieren. Genau das soll diese Einstellung bewirken.

Die Tokens pro Sekunde brechen unter Last auf einem CPU-Server ein. Führen Sie währenddessen vmstat 1 aus. Werte ungleich 0 in den Spalten si und so bedeuten, dass der Rechner den Swap verwendet. Die Gewichte werden dann für jedes Token vom Datenträger gelesen. Keine Konfigurationsänderung kann das ausgleichen. Verwenden Sie ein kleineres Modell oder reduzieren Sie die Anzahl der Slots.

Einer von zehn Benutzern wartet deutlich länger als die übrigen. Suchen Sie im vLLM-Log nach preempted. Preemption und die anschließende Neuberechnung sind in der Regel die Ursache. Das bedeutet, dass der Cache für die zulässige Kontextlänge zu klein ist.

TTFT ist schlecht, obwohl der Server im Leerlauf ist. Das betrifft das Prefill, nicht die Parallelverarbeitung. Lange Prompts benötigen bereits vor dem ersten Token erhebliche Zeit. Prüfen Sie daher zunächst die Promptgröße und das Prefix-Caching, bevor Sie die Hardware untersuchen. Tritt die lange Wartezeit nur beim ersten Benutzer nach einer längeren Ruhephase auf und sind alle nachfolgenden Anfragen unauffällig, handelt es sich nicht um Prefill. In diesem Fall hat Ollama das Modell entladen und liest die Gewichte erneut vom Datenträger. Das lässt sich ausschließen, indem Sie das Modell zwischen Anfragen im Speicher halten.

FAQ

Warum wird mein selbst gehostetes LLM langsamer, wenn eine zweite Person es verwendet?

Meistens wird es überhaupt nicht langsamer. Die Anfrage wird in eine Warteschlange gestellt. Ollama wird mit OLLAMA_NUM_PARALLEL auf 1 ausgeliefert, daher wartet die zweite Anfrage, bis die erste ihr letztes Token ausgegeben hat. Unterscheiden Sie die beiden Fälle, indem Sie den Stream eines Benutzers messen, während eine andere Anfrage wartet: Wenn die Tokenrate pro Sekunde nach dem Start normal ist, liegt eine Warteschlange vor, und eine Erhöhung der Anzahl paralleler Anfragen behebt das Problem. Wenn beide Streams mit halber Geschwindigkeit laufen, teilen sie sich tatsächlich die Speicherbandbreite. Das ist eine Hardwaregrenze.

Wie viele gleichzeitige Benutzer kann eine kleine GPU bedienen?

Berechnen Sie den Speicherbedarf, nicht die Benutzerzahl. Zuerst kommen die Gewichte, danach der KV-Cache. Dieser benötigt pro Token und aktiver Unterhaltung 2 mal Layer mal Key/Value-Heads mal Head-Dimension mal Bytezahl. Ein typisches 8B-Modell mit 36 Layern, 8 Key/Value-Heads und einer Head-Dimension von 128 benötigt bei 16 Bit etwa 144 KiB pro Token. Eine Unterhaltung mit 8,192 Token benötigt daher ungefähr 1.2 GB. Eine 24-GB-Karte, die dieses Modell mit 16 Bit hält, hat etwa 6 GB für den Cache übrig. Das reicht für ungefähr fünf Unterhaltungen mit vollem Kontext oder für mehr Unterhaltungen bei kürzerem Kontext.

Macht kontinuierliches Batching die Antwort für jeden Benutzer langsamer?

Die mediane Latenz verbessert sich normalerweise, weil Anfragen nicht mehr auf den Abschluss eines gesamten Batches warten. Die Tail-Latenz wird schlechter. Jede zusätzliche Sequenz verursacht bei jedem Decoding-Schritt zusätzlichen Aufwand. Das Prefill einer neu eingetroffenen Anfrage beansprucht einen Teil eines Schritts der gerade laufenden Streams. Eine unterbrochene Anfrage muss außerdem zweimal prefilt werden. Messen Sie die p95-Latenz zwischen den Token und nicht den Durchschnitt. Ein Chatfenster macht Pausen deutlich sichtbar, die ein Durchschnittswert verbergen kann.

Sollte ich OLLAMA_NUM_PARALLEL erhöhen oder zu vLLM wechseln?

Erhöhen Sie zuerst die Anzahl paralleler Anfragen. Das ist kostenlos, erfordert nur eine Drop-in-Datei und behebt den häufigen Fall, dass vier Personen hinter einer langen Antwort warten. Der Speicher ist die Begrenzung: Parallele Anfragen vervielfachen den erforderlichen Kontext. Achten Sie daher darauf, ob Layer auf die CPU ausgelagert werden. Wechseln Sie zu vLLM, wenn Ihre GPU noch VRAM frei hat und tatsächlich mehr als ungefähr vier Anfragen gleichzeitig aktiv sind. Ab diesem Punkt bringen paged Cache und Scheduling pro Token mehr Vorteile, als sie Kosten verursachen.

Beheben mehr CPU-Kerne einen langsamen LLM-Server?

Nicht bei dem Teil, den Benutzer am stärksten wahrnehmen. Beim Decoding wird das gesamte Modell für jedes Token aus dem Speicher gelesen. Daher ist die Geschwindigkeit durch die RAM-Bandbreite begrenzt. Zusätzliche Kerne helfen nicht mehr, sobald die Bandbreite ausgelastet ist. Das Prefill skaliert dagegen mit der Anzahl der Kerne. Mehr Kerne verkürzen daher bei langen Prompts die Zeit bis zum ersten Token. Auf einer VPS mit 4 bis 8 GB ist normalerweise die Speicherkapazität der begrenzende Faktor. Die wirksame Lösung ist dann ein kleineres Modell oder ein kürzerer Kontext und nicht mehr vCPUs.