SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-13

Ollama 如何設定 num_ctx 與 context length?

Ollama 預設 context window 可能只有 2048 或 4096 tokens,長提示詞會靜默截斷。了解如何逐次請求或全域設定 num_ctx,並估算提高後的 KV cache RAM。

num_ctx 的作用,以及長提示詞為何遭到截斷

Ollama 的 context length 是已載入模型一次可在記憶體中容納的 token 數量,而 num_ctx 是用來設定此值的選項。Ollama 選用的預設值遠低於模型宣告的最大值,因此較長的提示詞會在模型讀取前遭到截斷。回應內容不會告訴你這件事已經發生。

Ollama model library 將 Llama 3.1 8B 列為支援 128k context window。但標準伺服器不會提供這麼大的值。Ollama 自己的文件在不同頁面列出不同的預設值:FAQ 表示為 4096 tokens,Modelfile reference 表示 num_ctx 預設為 2048,而 context length 頁面 表示預設值會依可用的 VRAM(video RAM)決定:低於 24 GiB 時為 4k,24 至 48 GiB 時為 32k,高於 48 GiB 時為 256k。這些說法各自曾適用於某些版本。這項差異帶來的實用教訓是:請直接從你自己的執行中伺服器讀取數值,不要盲目相信任何頁面,包括本頁。

截斷不易察覺,因為模型仍會回答,而且回答讀起來仍然合理。只是模型實際上是根據你輸入內容的後半段產生回答。遺漏文件前半部的摘要看起來像是模型能力不足,但通常只是 context window 太小。

檢查伺服器實際套用的 Ollama context length

適用於任何 build 的檢查方式是 prompt_eval_count,也就是伺服器回報已處理的 prompt token 數量。傳送超過 context 可容納的內容後,該數值會停在上限。

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}'

該 prompt 約有 18,000 個單字,遠超過 4096 個 token。因此,prompt_eval_count 會接近 4096,而不是接近實際 token 數量,因為伺服器捨棄了超出的內容。改用 "num_ctx":16384 再執行一次,計數就會上升。如果你的 build 回傳錯誤而不是截斷內容,這仍表示相同的結果,只是訊號更明顯。

ollama ps

在會列印該欄位的 build 中,CONTEXT 欄顯示目前載入的模型實際使用的 context length。旁邊的 PROCESSOR 欄顯示模型目前使用的位置。沒有 GPU 的 VPS 通常會顯示 100% CPU。GPU 主機若顯示類似 30%/70% CPU/GPU 的分割,表示權重與 cache 已無法同時容納於 VRAM,通常原因是 num_ctx 被調高。

journalctl -u ollama --no-pager | grep -i n_ctx | tail -n 5

inference runner 會在包含 n_ctx 的行中列出 context size。不同 release 的確切文字可能不同,因此缺少該行時,應先視為名稱變更,不要據此判定其他結論。

設定 num_ctx 的四個位置

在請求中。"options": {"num_ctx": 16384} 傳送至 /api/generate/api/chat。這會覆寫其他所有設定,且只套用於該次呼叫。如果這個值與已載入模型目前使用的值不同,伺服器會先重新載入模型。你可以在回應的 load_duration 中看到這點:數值會從接近零跳升至數秒。

在互動工作階段中。ollama run 內輸入 /set parameter num_ctx 16384。這只會持續至該工作階段結束。

在 Modelfile 中。 這會將值寫入指定名稱的模型,因此所有用戶端都會取得該值,不必在用戶端變更設定。

FROM llama3.1:8b
PARAMETER num_ctx 16384
ollama create llama3.1-16k -f ./Modelfile
ollama run llama3.1-16k

在伺服器上。 OLLAMA_CONTEXT_LENGTH 會為未攜帶自有 num_ctx 的所有請求設定預設值。在 systemd 下,請新增 drop-in,不要編輯 unit file。

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_CONTEXT_LENGTH=16384"
sudo systemctl daemon-reload
sudo systemctl restart ollama
ollama ps

在除錯他人的用戶端時,優先順序最重要。攜帶 num_ctx 的請求會覆寫伺服器預設值,因此 chat 前端或 agent 若自行傳送較小的值,就會悄悄抵銷你對 systemd 所做的變更。當你將 coding agent 指向 Ollama 伺服器時,請先確認用戶端傳送的內容,再判斷問題是否出在伺服器。

Why you cannot just set num_ctx to the model maximum

Attention makes every token look at every token before it. The keys and values computed for earlier tokens are kept so they are not recomputed for each new token, and that store is the KV cache (key/value cache). It is allocated for the whole of num_ctx when the model loads, not as the conversation grows, so a large context costs its memory even on a one line prompt.

DigitalOcean's inference cost tutorial states the arithmetic in one line:

kv_bytes_per_token = 2 * layers * kv_heads * head_dim * bytes_per_value

The 2 counts keys and values separately. Read the other numbers off your own model.

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 reports 32 layers and 8 key/value heads. The head dimension is embed divided by heads, so 4096 / 32 = 128 here, and some models publish it directly as llama.attention.key_length. The default cache holds f16 values, so bytes_per_value is 2, and 2 32 8 128 2 works out at 131,072 bytes. That is 128 KiB of cache for every single token of context. Multiply by the context length and the cost stops being abstract.

ChartLlama 3.1 8B at f16: KV cache and total RAM by context length, in GiB
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
  }
]

Those 6 rows are arithmetic from the formula above, not measurements. The total column adds the 4.9 GB download that the Ollama library listed for llama3.1:8b in August 2026, which is 4.6 GiB, and it leaves out the compute buffers and the server process itself. Treat it as a floor.

The shape is the point. At 8k the cache costs 1 GiB, which is noise next to the weights. At the model's full 128k it costs 16 GiB, more than three times the weights, for a total near 20.6 GiB. So a 4 GB VPS cannot load this model at any useful context. An 8 GB VPS is comfortable at 8k. A 16 GB VPS reaches 32k with room left for the rest of the box. Every one of those thresholds moves up with the weights, so if you are weighing a larger model against this 8B, the same sums worked through for Qwen's 27B tag on a CPU-only VPS show how little the weights leave over for context between 8 and 64 GB.

KV cache 無法容納時會發生什麼

在僅使用 CPU 的 VPS 上,程序會持續增加記憶體用量。模型載入期間及執行長時間請求時,請監控其狀態。

free -m
ps -eo rss,comm --sort=-rss | head -n 5

RSS(resident set size)會以 kilobytes 顯示。如果 free -m 中的 swap 使用量開始增加,請降低 context 設定。KV cache 若位於 swap 中,生成每個 token 都必須讀取整個 cache,因此每個 token 可能會停頓數秒。

如果主機完全耗盡記憶體,kernel 會選擇最大的程序並將其終止。

sudo dmesg | grep -i "killed process"

顯示 Out of memory: Killed process 1234 (ollama) 的行表示你要求的 context 無法容納。Ollama 通常會在到達這一步前拒絕請求,接著顯示錯誤訊息,說明所需的記憶體與當時可用的記憶體。

在 GPU 主機上,失敗情況不會那麼明顯。部分 layers 會溢出到系統 RAM,ollama ps 會顯示 CPU 與 GPU 的分配情況,而 throughput 會大幅下降。實際下降幅度取決於硬體,因此請在每個 context 設定下,測量你自己主機每秒可生成的 token 數量,不要直接採用其他機器上的數值。

Prefill 時間增長速度高於 prompt

Prefill 是在第一個輸出 token 出現前,針對輸入內容執行的處理。每個 prompt token 都會注意其前方的所有 token,因此總處理量會隨輸入長度的平方增長。prompt 長度加倍時,等待第一個 token 的時間會增加超過一倍。

回應中包含測量結果,因此不必直接相信這項說法。

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)}'

使用短 prompt 執行一次,再使用長 prompt 執行一次,然後分別以 token 數除以秒數。在僅使用 CPU 的 VPS 上,Prefill 通常是長 context 請求中最慢的部分;使用短 prompt 測得的 tokens per second 數值,無法預測長 prompt 的表現。

這個問題在並行處理時最明顯。每個正在服務的請求都需要自己的 cache,因此上方圖表中的記憶體用量是每個請求的用量,不是整台伺服器的用量。單一長請求可能長時間占用整台主機,讓短請求在後方排隊。請審慎設定 OLLAMA_NUM_PARALLEL,並先閱讀 自架 LLM 可服務多少並行使用者,再同時提高這兩個數值。

Buy context back with a smaller cache

bytes_per_value in the formula is a setting you control. Ollama's FAQ documents OLLAMA_KV_CACHE_TYPE, with f16 as the default at 2 bytes, plus q8_0 at 1 byte and q4_0 below that. Moving to q8_0 halves the cache, so the 32k row costs 2 GiB instead of 4 GiB. The same FAQ documents OLLAMA_FLASH_ATTENTION=1, which some builds want before a quantised cache takes effect.

[Service]
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"

Confirm rather than assume: restart the service, load the model at the same num_ctx as before, and compare RSS. Support depends on the model and on the backend, so a setting that changes nothing means your combination is not covered. The documentation lists these options without promising a quality result, so test q4_0 against your own prompts before you rely on it. If these knobs are the reason you are here, Ollama and llama.cpp expose them differently.

設定 num_ctx 的方法

  1. /api/show 讀取模型的最大上下文長度、層數,以及 key/value head 數量。
  2. 使用公式計算每個 token 所需的位元組數,再乘以所需的上下文長度。
  3. 加上權重大小,與可用 RAM 比較,並至少保留 1 GiB 給主機上的其他服務。
  4. 設定數值並載入模型,再使用 ollama psprompt_eval_count 確認實際套用的設定。
  5. 執行實際工作負載,同時監控 free -m。如果 swap 開始活動,將上下文長度減半。

多數工作所需的上下文長度都比使用者設定的值小。摘要長篇報告使用 16k 通常已足夠。檢索前端貼入 5 個文件片段時,很少會超過 8k。需要讀取完整檔案的 coding agent 才是真正需要 64k 或更大的情況;在這種情況下,應依上下文長度規劃主機規格,而不是反過來。如果伺服器仍是新建的,請先從 在 VPS 上正常運作的 Ollama 安裝 開始,等模型能正常載入後再調整上下文長度。

FAQ

Ollama 的預設 context length 是多少?

這取決於 build 與硬體,因此應查證,不要直接假設。Ollama 的 FAQ 記載為 4096 tokens,Modelfile reference 記載 num_ctx 預設值為 2048,而 context length 頁面則說明會依可用 VRAM 選擇預設值:低於 24 GiB 時為 4k,24 至 48 GiB 時為 32k,高於 48 GiB 時為 256k。僅使用 CPU 的 VPS 會落在較小的範圍。具備該欄位的 build 可透過 ollama ps 顯示實際套用的 context,任何 build 都能透過 API 回應中的 prompt_eval_count 加以確認。

為什麼 Ollama 會忽略長 prompt 的開頭?

因為 prompt 長度超過 context window,伺服器在模型讀取前就將其截斷,而且不會回傳錯誤。使用較大的 num_ctx 再次傳送相同 prompt,並觀察回應中的 prompt_eval_count 是否增加。若該數值沒有變化,表示用戶端與伺服器之間的某個元件自行設定了 num_ctx;chat front end 與 agent framework 很常出現這種情況。

較大的 num_ctx 需要多少額外 RAM?

將 context length 乘以每個 token 的 cache 成本,該成本為 2 * layers * kv_heads * head_dim * bytes_per_value。以 f16 的 Llama 3.1 8B 為例,每個 token 需要 128 KiB,因此 32k tokens 會額外耗用 4 GiB,而完整的 128k 則會在 weights 之外額外耗用 16 GiB。模型載入時就會配置 cache,因此較大的 num_ctx 即使在 prompt 很短時,也會占用這些記憶體。

較大的 context window 會讓 Ollama 變慢嗎?

會,原因有兩個。Prefill 工作量會隨 prompt 長度的平方增加,因此較長的輸入會讓第一個 token 的產生時間延後,幅度會超過單純依長度推算的結果。較大的 cache 也會競爭記憶體:在 GPU 主機上,會將部分 layers 推入 system RAM;在 CPU 主機上,則會使系統更容易使用 swap。即使從未填滿的較大 num_ctx,仍會占用相應的記憶體,但不會增加 prefill 時間。

可以為單一 model 永久設定 num_ctx 嗎?

可以。建立包含 FROM llama3.1:8bPARAMETER num_ctx 16384 的 Modelfile,然後執行 ollama create llama3.1-16k -f ./Modelfile。所有要求 llama3.1-16k 的 client 都會套用該 context,不必另外傳送 options。若 request 自行帶有 num_ctx,仍會優先採用該設定,因此這是預設值,而不是上限。