Ollama num_ctx richtig setzen und Kontextlänge erhöhen
Lange Ollama-Eingaben werden beim kleinen Standardwert abgeschnitten. Setzen Sie num_ctx pro Anfrage oder serverweit und prüfen Sie den KV-Cache-RAM vor der Erhöhung.
Was num_ctx bewirkt und warum Ihre lange Eingabe abgeschnitten wurde
Die Ollama-Kontextlänge gibt an, wie viele Tokens ein geladenes Modell gleichzeitig im Speicher halten kann. num_ctx ist die Option, die diesen Wert festlegt. Ollama verwendet einen Standardwert, der deutlich unter dem vom Modell angegebenen Maximum liegt. Deshalb wird eine längere Eingabe abgeschnitten, bevor das Modell sie überhaupt verarbeitet. Die Antwort enthält keinen Hinweis darauf, dass dies geschehen ist.
Llama 3.1 8B wird in der Ollama-Modellbibliothek mit einem Kontextfenster von 128k angegeben. Ein unveränderter Server stellt diesen Wert nicht automatisch bereit. Die eigene Dokumentation von Ollama nennt auf verschiedenen Seiten unterschiedliche Standardwerte: Die FAQ nennt 4096 Tokens, die Modelfile-Referenz gibt für num_ctx den Standardwert 2048 an, und auf der Seite zur Kontextlänge steht, dass der Standardwert anhand des verfügbaren VRAM (Video-RAM) gewählt wird: 4k bei weniger als 24 GiB, 32k bei 24 bis 48 GiB und 256k darüber. Jeder dieser Werte war in bestimmten Builds korrekt. Daraus ergibt sich eine wichtige Schlussfolgerung: Lesen Sie den Wert auf Ihrem eigenen laufenden Server aus, statt einer beliebigen Dokumentationsseite zu vertrauen, auch nicht dieser.
Die Kürzung bleibt unbemerkt, weil das Modell weiterhin antwortet und die Antwort weiterhin plausibel klingt. Das Modell hat die Antwort aus dem letzten Teil Ihrer Eingabe erstellt. Eine Zusammenfassung, in der die erste Hälfte eines Dokuments fehlt, wirkt wie die Ausgabe eines schwachen Modells. Ursache ist meist ein zu kleines Kontextfenster.
Prüfen, welche Ollama-Kontextlänge Ihr Server tatsächlich verwendet
Die Prüfung, die mit jedem Build funktioniert, ist prompt_eval_count. Das ist die Anzahl der Prompt-Tokens, deren Verarbeitung der Server meldet. Senden Sie mehr Tokens, als der Kontext aufnehmen kann, bleibt diese Zahl am Limit stehen.
sudo apt update && sudo apt install -y jq
LONG=$(python3 -c "print('the quick brown fox jumps over the lazy dog. ' * 2000)")
jq -n --arg p "$LONG" '{model:"llama3.1:8b", prompt:$p, stream:false, options:{num_ctx:4096}}' |
curl -s http://localhost:11434/api/generate -d @- |
jq '{prompt_eval_count, prompt_eval_duration}'Dieser Prompt umfasst etwa 18,000 Wörter und damit deutlich mehr als 4096 Tokens. prompt_eval_count liefert einen Wert nahe 4096 statt nahe der tatsächlichen Token-Anzahl, weil der Server den Rest verworfen hat. Führen Sie den Befehl erneut mit "num_ctx":16384 aus. Dann steigt der Zähler. Gibt Ihr Build statt einer Kürzung einen Fehler zurück, ist das dieselbe Feststellung mit einem deutlicheren Signal.
ollama psDie Spalte CONTEXT enthält bei Builds, die sie ausgeben, die Kontextlänge, mit der das geladene Modell aktuell läuft. Die danebenstehende Spalte PROCESSOR zeigt, wo sich das Modell befindet. 100% CPU ist auf einem VPS ohne GPU normal. Eine Aufteilung wie 30%/70% CPU/GPU auf einem GPU-Server bedeutet, dass die Gewichte und der Cache nicht mehr gemeinsam in den VRAM passen. Ein erhöhter Wert für num_ctx ist dafür der übliche Grund.
journalctl -u ollama --no-pager | grep -i n_ctx | tail -n 5Der Inference Runner gibt seine Kontextgröße in einer Zeile aus, die n_ctx enthält. Der genaue Wortlaut ändert sich zwischen Releases. Behandeln Sie eine fehlende Zeile daher als Umbenennung und nicht als Beweis für eine bestimmte Konfiguration.
Vier Stellen zum Setzen von num_ctx
In der Anfrage. Senden Sie "options": {"num_ctx": 16384} an /api/generate oder /api/chat. Diese Einstellung hat Vorrang vor allen anderen und gilt nur für diesen Aufruf. Unterscheidet sich der Wert von der Einstellung, mit der das geladene Modell ausgeführt wird, lädt der Server das Modell zuerst neu. Das sehen Sie in load_duration in der Antwort: Der Wert steigt von nahezu null auf mehrere Sekunden.
In der interaktiven Sitzung. Geben Sie innerhalb von ollama run /set parameter num_ctx 16384 ein. Die Einstellung gilt für diese Sitzung.
In einer Modelfile. Dadurch wird der Wert in ein benanntes Modell übernommen. Jeder Client erhält ihn dann ohne clientseitige Änderung.
FROM llama3.1:8b
PARAMETER num_ctx 16384ollama create llama3.1-16k -f ./Modelfile
ollama run llama3.1-16kAuf dem Server. OLLAMA_CONTEXT_LENGTH legt den Standardwert für jede Anfrage fest, die keinen eigenen Wert für num_ctx enthält. Verwenden Sie unter systemd ein Drop-in, statt die Unit-Datei zu bearbeiten.
sudo systemctl edit ollama.service[Service]
Environment="OLLAMA_CONTEXT_LENGTH=16384"sudo systemctl daemon-reload
sudo systemctl restart ollama
ollama psDie Priorität ist besonders wichtig, wenn Sie den Client einer anderen Person untersuchen. Eine Anfrage mit num_ctx hat Vorrang vor dem Serverstandard. Ein Chat-Frontend oder ein Agent, der selbst einen kleinen Wert sendet, setzt Ihre systemd-Änderung dadurch unbemerkt außer Kraft. Wenn Sie einen Coding-Agent auf Ihren Ollama-Server verweisen, prüfen Sie, was der Client sendet, bevor Sie den Server als Ursache ansehen.
Warum Sie num_ctx nicht einfach auf das Modellmaximum setzen können
Bei der Attention betrachtet jedes Token alle vorherigen Tokens. Die für frühere Tokens berechneten Keys und Values werden gespeichert, damit sie nicht für jedes neue Token erneut berechnet werden müssen. Dieser Speicher ist der KV-Cache (Key/Value-Cache). Er wird beim Laden des Modells für die gesamte num_ctx reserviert und wächst nicht mit der Unterhaltung. Ein großer Kontext belegt seinen Speicher daher auch bei einem einzeiligen Prompt.
Der Kostenleitfaden für Inference von DigitalOcean stellt die Berechnung in einer Zeile dar:
kv_bytes_per_token = 2 * layers * kv_heads * head_dim * bytes_per_valueDie 2 zählt Keys und Values getrennt. Die übrigen Zahlen entnehmen Sie Ihrem eigenen Modell.
curl -s http://localhost:11434/api/show -d '{"model":"llama3.1:8b"}' |
jq '.model_info | {ctx: ."llama.context_length", layers: ."llama.block_count", heads: ."llama.attention.head_count", kv_heads: ."llama.attention.head_count_kv", embed: ."llama.embedding_length"}'Llama 3.1 8B verwendet laut Angaben 32 Layer und 8 Key/Value-Heads. Die Head-Dimension ergibt sich aus embed geteilt durch heads, also hier 4096 / 32 = 128. Einige Modelle veröffentlichen diesen Wert direkt als llama.attention.key_length. Der Standard-Cache speichert Werte im f16-Format, daher ist bytes_per_value gleich 2. Die Berechnung 2 32 8 128 2 ergibt 131,072 Bytes. Das entspricht 128 KiB Cache für jedes einzelne Kontext-Token. Multipliziert mit der Kontextlänge werden die Kosten konkret.
The data behind this chart
[
{
"label": "4k",
"kv_cache_gib": 0.5,
"total_ram_gib": 5.1
},
{
"label": "8k",
"kv_cache_gib": 1,
"total_ram_gib": 5.6
},
{
"label": "16k",
"kv_cache_gib": 2,
"total_ram_gib": 6.6
},
{
"label": "32k",
"kv_cache_gib": 4,
"total_ram_gib": 8.6
},
{
"label": "64k",
"kv_cache_gib": 8,
"total_ram_gib": 12.6
},
{
"label": "128k",
"kv_cache_gib": 16,
"total_ram_gib": 20.6
}
]Diese 6 Zeilen sind Berechnungen anhand der obigen Formel und keine Messwerte. Die Spalte total addiert den 4.9-GB-Download, den die Ollama-Bibliothek für llama3.1:8b im August 2026 angegeben hat. Das entspricht 4.6 GiB. Rechenpuffer und der Serverprozess selbst sind nicht enthalten. Betrachten Sie den Wert als Untergrenze.
Entscheidend ist die Größenordnung. Bei 8k belegt der Cache 1 GiB. Das fällt gegenüber den Gewichten kaum ins Gewicht. Beim vollständigen Kontext von 128k belegt er 16 GiB. Das ist mehr als das Dreifache der Gewichte. Insgesamt ergibt sich ein Wert von etwa 20.6 GiB. Ein VPS mit 4 GB kann dieses Modell daher mit keinem praktisch nutzbaren Kontext laden. Ein VPS mit 8 GB bietet bei 8k ausreichend Spielraum. Ein VPS mit 16 GB erreicht 32k und lässt noch Speicher für die übrigen Dienste des Systems. Mit den Gewichten verschieben sich alle diese Grenzen nach oben. Wenn Sie ein größeres Modell mit diesem 8B-Modell vergleichen, zeigen die gleichen Berechnungen für Qwens 27B-Tag auf einem CPU-only-VPS, wie wenig Speicher zwischen 8 und 64 GB für den Kontext übrig bleibt.
Was passiert, wenn der KV-Cache nicht in den Speicher passt
Auf einer VPS ohne GPU wächst der Prozess einfach weiter. Überwachen Sie ihn, während das Modell geladen wird und während eine lange Anfrage ausgeführt wird.
free -m
ps -eo rss,comm --sort=-rss | head -n 5RSS (resident set size) wird in Kilobyte ausgegeben. Wenn der verwendete Swap in free -m zunimmt, reduzieren Sie den Kontext. Ein KV-Cache im Swap lässt die Generierung mehrere Sekunden pro Token warten, weil jeder neue Token den gesamten Cache liest.
Wenn der Arbeitsspeicher des Systems vollständig erschöpft ist, wählt der Kernel den größten Prozess aus und beendet ihn.
sudo dmesg | grep -i "killed process"Eine Zeile mit Out of memory: Killed process 1234 (ollama) bedeutet, dass der angeforderte Kontext nicht in den Speicher passte. Ollama verweigert die Ausführung häufig bereits vorher. Die Anfrage schlägt dann mit einer Meldung fehl, die den benötigten Speicher dem freien Speicher gegenüberstellt.
Auf einem System mit GPU ist der Fehler weniger offensichtlich. Layer werden in den Arbeitsspeicher ausgelagert, ollama ps zeigt die Aufteilung zwischen CPU und GPU, und der Durchsatz sinkt stark. Wie stark er sinkt, hängt von Ihrer Hardware ab. Messen Sie daher die Tokens pro Sekunde auf Ihrem eigenen System für jede Kontexteinstellung, statt einer Angabe von einem anderen System zu vertrauen.
Die Prefill-Zeit steigt schneller als die Prompt-Länge
Prefill bezeichnet die Verarbeitung Ihrer Eingabe, bevor das erste Ausgabetoken erscheint. Jedes Prompt-Token verarbeitet alle vorhergehenden Tokens. Dadurch steigt der Gesamtaufwand quadratisch mit der Eingabelänge. Wenn Sie den Prompt verdoppeln, mehr als verdoppelt sich die Wartezeit bis zum ersten Token.
Die Antwort enthält die Messwerte. Sie müssen diese daher nicht ungeprüft übernehmen.
jq -n --arg p "$LONG" '{model:"llama3.1:8b", prompt:$p, stream:false, options:{num_ctx:16384}}' |
curl -s http://localhost:11434/api/generate -d @- |
jq '{tokens: .prompt_eval_count, prefill_seconds: (.prompt_eval_duration/1000000000)}'Führen Sie den Befehl mit einem kurzen Prompt und anschließend mit einem langen Prompt aus. Teilen Sie in beiden Fällen die Tokenanzahl durch die Sekunden. Auf einer CPU-only-VPS ist Prefill bei Anfragen mit langem Kontext normalerweise der langsamste Teil. Ein Tokens-per-Second-Wert, der mit einem kurzen Prompt ermittelt wurde, sagt daher nichts Verlässliches über die tatsächliche Geschwindigkeit aus.
Besonders deutlich zeigt sich dieses Problem bei gleichzeitiger Verarbeitung. Für jede Anfrage benötigt der Dienst einen eigenen Cache. Der Speicherbedarf in der obigen Tabelle gilt daher pro Anfrage und nicht pro Server. Eine einzelne lange Anfrage kann den Server auslasten, während kurze Anfragen dahinter warten. Setzen Sie OLLAMA_NUM_PARALLEL bewusst, und lesen Sie nach, wie viele gleichzeitige Benutzer ein selbst gehostetes LLM bedienen kann, bevor Sie beide Werte gleichzeitig erhöhen.
Kontext mit einem kleineren Cache zurückgewinnen
bytes_per_value in der Formel ist eine Einstellung, die Sie steuern können. Die FAQ von Ollama dokumentiert OLLAMA_KV_CACHE_TYPE, wobei f16 mit standardmäßig 2 Bytes angegeben ist. Außerdem werden q8_0 mit 1 Byte und q4_0 darunter dokumentiert. Der Wechsel zu q8_0 halbiert den Cache. Dadurch kostet die Zeile mit 32k 2 GiB statt 4 GiB. Dieselbe FAQ dokumentiert OLLAMA_FLASH_ATTENTION=1. Einige Builds benötigen diese Einstellung, damit ein quantisierter Cache wirksam wird.
[Service]
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"Gehen Sie nicht von der Wirkung aus, sondern überprüfen Sie sie: Starten Sie den Dienst neu, laden Sie das Modell mit demselben num_ctx wie zuvor und vergleichen Sie den RSS-Wert. Die Unterstützung hängt vom Modell und vom Backend ab. Wenn eine Einstellung nichts ändert, wird Ihre Kombination nicht unterstützt. Die Dokumentation listet diese Optionen auf, ohne ein bestimmtes Ergebnis hinsichtlich der Qualität zu versprechen. Testen Sie daher q4_0 mit Ihren eigenen Prompts, bevor Sie sich darauf verlassen. Wenn diese Einstellungen der Grund für Ihre Suche sind, stellen Ollama und llama.cpp sie unterschiedlich bereit.
Eine Anleitung zur Wahl von num_ctx
- Lesen Sie den maximalen Kontext des Modells, seine Layer-Anzahl und die Anzahl seiner Key/Value-Heads aus
/api/showab. - Ermitteln Sie mit der Formel die Byte-Anzahl pro Token und multiplizieren Sie sie anschließend mit dem gewünschten Kontext.
- Addieren Sie die Größe der Gewichte, vergleichen Sie das Ergebnis mit dem freien RAM und lassen Sie mindestens 1 GiB für die übrigen Prozesse des Servers frei.
- Setzen Sie den Wert, laden Sie das Modell und prüfen Sie anschließend mit
ollama psundprompt_eval_count, welcher Wert übernommen wurde. - Führen Sie Ihre reale Arbeitslast aus und beobachten Sie dabei
free -m. Halbieren Sie den Kontext, sobald Swap-Nutzung einsetzt.
Die meisten Aufgaben benötigen weniger Kontext, als häufig eingestellt wird. Zum Zusammenfassen eines langen Berichts reichen 16k. Ein Retrieval-Frontend, das fünf Dokumentabschnitte einfügt, überschreitet selten 8k. Ein Coding-Agent, der vollständige Dateien einliest, benötigt tatsächlich 64k oder mehr. In diesem Fall sollten Sie die Maschine anhand des Kontexts dimensionieren und nicht umgekehrt. Wenn der Server noch neu ist, beginnen Sie mit einer funktionierenden Ollama-Installation auf einem VPS und optimieren Sie den Kontext, sobald die Modelle fehlerfrei geladen werden.
FAQ
Wie lang ist der Standardkontext in Ollama?
Das hängt vom Build und von der Hardware ab. Prüfen Sie den Wert daher, statt ihn vorauszusetzen. Die Ollama-FAQ nennt 4096 Token, die Modelfile-Referenz dokumentiert einen num_ctx-Standardwert von 2048, und die Seite zur Kontextlänge nennt einen Standardwert, der anhand des verfügbaren VRAM ausgewählt wird: 4k bei weniger als 24 GiB, 32k bei 24 bis 48 GiB und 256k bei mehr als 48 GiB. Ein CPU-only-VPS liegt am unteren Ende. ollama ps gibt bei Builds mit dieser Spalte den tatsächlich verwendeten Kontext aus. prompt_eval_count in einer API-Antwort bestätigt ihn bei jedem Build.
Warum ignoriert Ollama den Anfang meines langen Prompts?
Der Prompt war länger als das Kontextfenster. Deshalb hat der Server ihn gekürzt, bevor das Modell ihn verarbeiten konnte. Es wurde kein Fehler zurückgegeben. Senden Sie denselben Prompt erneut mit einem größeren num_ctx und beobachten Sie, ob prompt_eval_count in der Antwort größer wird. Wenn sich dieser Wert nicht ändert, setzt eine Komponente zwischen Ihnen und dem Server num_ctx selbst. Das ist bei Chat-Frontends und Agent-Frameworks häufig.
Wie viel zusätzlichen RAM benötigt ein größeres num_ctx?
Multiplizieren Sie die Kontextlänge mit den Cache-Kosten pro Token. Diese betragen 2 * layers * kv_heads * head_dim * bytes_per_value. Bei Llama 3.1 8B mit f16 sind das 128 KiB pro Token. 32k Token benötigen daher 4 GiB. Die vollständigen 128k benötigen zusätzlich zu den Gewichten 16 GiB. Der Cache wird beim Laden des Modells reserviert. Ein großes num_ctx belegt diesen Speicher daher auch dann, wenn Ihre Prompts kurz bleiben.
Macht ein größeres Kontextfenster Ollama langsamer?
Ja, aus zwei Gründen. Der Prefill-Aufwand steigt mit dem Quadrat der Prompt-Länge. Eine lange Eingabe verzögert das erste Token daher stärker, als es ihre Länge vermuten lässt. Außerdem konkurriert der größere Cache um Speicher. Auf einem GPU-System werden dadurch Layer in den System-RAM verschoben. Auf einem CPU-System wird dadurch die Nutzung des Swap wahrscheinlicher. Ein großes num_ctx verursacht die Speichernutzung auch dann, wenn Sie es nie vollständig ausnutzen. Die Prefill-Zeit steigt dadurch jedoch nicht.
Kann ich num_ctx dauerhaft für ein Modell festlegen?
Ja. Schreiben Sie ein Modelfile mit FROM llama3.1:8b und PARAMETER num_ctx 16384. Führen Sie anschließend ollama create llama3.1-16k -f ./Modelfile aus. Jeder Client, der llama3.1-16k anfordert, erhält diesen Kontext, ohne Optionen zu senden. Eine Anfrage mit einem eigenen num_ctx hat weiterhin Vorrang. Damit legen Sie einen Standardwert fest, keine Obergrenze.