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

KV cache 與 prompt cache 有什麼不同?

KV cache 會隨請求占用 RAM 或 VRAM,耗盡可能導致模型拒絕載入;prompt cache 則是供應商的計費折扣,未命中只會恢復完整價格。

KV cache 與 prompt cache:簡短答案

KV cache 與供應商的 prompt cache 共用一個詞,幾乎沒有其他相似之處。KV cache 是每個請求的工作記憶體。它會在單一請求的整個生命週期內,持續佔用伺服器的 RAM 或 VRAM,並隨著內容長度及同時執行的請求數量增加。供應商的 prompt caching 是一項計費與延遲功能。系統會將 prompt 中穩定的前綴儲存在供應商的伺服器上;下次再次傳送時,這部分會以折扣價格計費。

前者是你以硬體成本購買的記憶體。後者是由其他人代為保存,並向你收取租金的記憶體。

實務上的差異比定義更重要。KV cache 可能耗盡;耗盡時,模型會拒絕載入,或請求會遭到拒絕。prompt cache 不會耗盡。你只可能無法命中快取,接著在不知不覺中支付完整價格。

KV cache 儲存的內容與存在原因

Transformer 產生第 500 個 token 時,必須對前面的 499 個 token 全部執行 attention。對這些 token 中的每一個,所有 layer 都需要一個 key vector 和一個 value vector。若每產生一個新 token 都重新計算這些向量,生成時間會隨序列長度的平方增加,因此 runtime 會將它們保留下來。這個儲存區就是 KV cache(key/value cache)。

KV cache 是每個 request 各自的狀態,因為它是根據該 request 的確切 token 序列建立的。兩個使用者若傳送不同的 prompt,就不能共用這個 cache;除非 runtime 啟用 prefix caching,這是稍後會說明的另一項功能。

Serving 分為兩個階段。Prefill 讀取完整的 prompt 並填入 cache,效能受限於計算能力。Decode 一次產生一個 token,並將其附加至 cache,效能受限於記憶體頻寬。這種分工會使 prompt 處理與 token 生成在你 測量自己主機每秒可處理的 token 數 時呈現不同的速度。

KV cache 會使用多少記憶體?

不要去查找廠商提供的表格。大小可以透過算式計算,任何模型都適用:

bytes per token = 2 * layers * kv_heads * head_dim * bytes per element

其中的 2 代表 key 和 value。其他數字都來自模型的 config.json,可在模型的 Hugging Face 頁面中查到。

以 Llama 3.1 8B 為例。其設定列出 num_hidden_layers 為 32,num_key_value_heads 為 8。hidden_size 為 4096,分布在 32 個 attention heads 中,因此每個 head 的維度是 128。使用 f16 時,每個元素占用 2 bytes:

2 * 32 * 8 * 128 * 2 = 131072 bytes = 128 KiB per token

將這個數值乘以你要求的 context,再乘以同時執行的請求數。

ChartLlama 3.1 8B KV cache at f16, in GiB
The data behind this chart
[
  {
    "label": "2k context",
    "one_request_gib": 0.25,
    "four_requests_gib": 1
  },
  {
    "label": "8k context",
    "one_request_gib": 1,
    "four_requests_gib": 4
  },
  {
    "label": "32k context",
    "one_request_gib": 4,
    "four_requests_gib": 16
  },
  {
    "label": "128k context",
    "one_request_gib": 16,
    "four_requests_gib": 64
  }
]

在 8k context 下,cache 為 1 GiB。到了 32k,則為 4 GiB,與 4-bit weights 本身的大小相近。使用模型完整的 128k context 時,單一請求會使用 16 GiB;如果 4 個請求都填滿 context,則會使用 64 GiB。Weights 從未改變,改變的只有 cache。

Grouped query attention (GQA) 對這個數值有很大影響。Llama 3.1 8B 有 8 個 key/value heads,服務 32 個 query heads,因此每 4 個 query heads 共用一組儲存的 key/value。若模型的 num_key_value_heads 等於 num_attention_heads,在參數數量相同的情況下,會使用 4 倍的 cache。在假設兩個 8B 模型的服務成本相同之前,先確認這個欄位。

為何能以 2k 執行的模型拒絕在 32k 載入

這是因為 runtime 會在模型載入時配置 KV cache,其大小取決於你設定的 context length,而不是實際送出的 prompt。Ollama 的預設 context window 是 4096 tokens。將其提高到 32k,代表在第一個 token 到達前,就要求額外配置 4 GiB。

OLLAMA_CONTEXT_LENGTH=32768 ollama serve

在互動式提示字元中,針對每個 session 使用相同設定:

ollama run llama3.1:8b
/set parameter num_ctx 32768

不同 stack 的錯誤表現不同。vLLM 會在啟動時檢查計算結果,並拒絕執行:

ValueError: The model's max seq len (131072) is larger than the maximum number of tokens that can be stored in KV cache (78336). Try increasing `gpu_memory_utilization` or decreasing `max_model_len` when initializing the engine.

在僅使用 CPU 的 VPS 上,不會進行這項檢查,因為配置的是一般系統 RAM。此時 kernel 的 out-of-memory killer 會終止該程序,並將證據留在 kernel ring buffer 中:

dmesg -T | grep -i "killed process"

若訊息列出你的 serving process,表示該主機承諾提供超出實際容量的記憶體。解決方法是縮小 context,而不是增大 swap file:每產生一個 token,都必須從磁碟讀取分頁到磁碟的 KV cache,因此生成速度會慢到無法使用。如何選擇合理的數值,請參閱我們的 Ollama num_ctx 與 context length 指南

並發如何影響數量

每個處理中的請求都會占用自己的 KV cache。這是多數容量規劃遺漏的部分。4 個各自維持 32k context 的使用者,彼此合計需要 16 GiB,此外還要加上權重所占的記憶體。

不同 runtime 對此的處理方式不同。Ollama 和 llama.cpp 在模型載入時會保留你指定的 context 大小,因此無論實際是否使用,這些記憶體都會被配置。vLLM 會將記憶體池切分為固定大小的區塊,並在每個請求增長時分配區塊,因此 500-token 的請求只會占用相當於 500 個 token 的空間。無論採用哪種方式,記憶體池都有上限;容量用滿後,新請求會排入佇列,而不會立即執行。如需了解排隊如何影響回應時間,請參閱 自架 LLM 可服務多少個並發使用者

讓 KV cache 變小的 4 種方法

  1. 降低 context length。這是影響最大、通常成本最低的方法。大多數聊天工作負載都不會接近 32k。
  2. 對 cache 本身進行量化。Ollama 的 OLLAMA_KV_CACHE_TYPE 預設使用 f16,也接受 q8_0;後者約使用一半記憶體,另有 q4_0,約使用四分之一。llama.cpp 對應的設定是 -ctk q8_0-ctv q8_0
  3. 選擇 key/value head 較少或 layer 較少的模型。下載 40 GB 的權重前,先閱讀 config.json
  4. 同時處理較少的請求,將其餘請求排入佇列。

q4_0 下,Llama 3.1 8B 每個 token 所需的記憶體會從 128 KiB 降至約 32 KiB,因此 32k 的 context 約需 1 GiB,而不是 4 GiB。這項節省並非沒有代價。key 和 value 會以較低精度儲存,因此請先使用自己的提示比較輸出,再決定是否保留此設定。

Provider prompt caching 實際帶來的效益

Provider prompt caching 是不同的產品,計費單位也不同。您會標記一段穩定的前綴,由 provider 儲存;之後若請求完全重複使用相同前綴,輸入內容會以較低費率計費,而不是按照完整輸入價格計費。

截至 2026 年 8 月,Anthropic 公布的倍率如下:5 分鐘快取寫入的費用是基本輸入 token 價格的 1.25 倍。1 小時寫入是 2 倍,快取讀取則是 0.1 倍。將 20,000-token 的 system prompt 套入這些數字後,這項方案的效益便很清楚。

ChartCost of a 20,000 token prefix, in base input token equivalents
The data behind this chart
[
  {
    "label": "No caching, every call",
    "billed_token_equivalents": "20,000"
  },
  {
    "label": "First call, 5 minute cache write",
    "billed_token_equivalents": "25,000"
  },
  {
    "label": "First call, 1 hour cache write",
    "billed_token_equivalents": "40,000"
  },
  {
    "label": "Every later call, cache hit",
    "billed_token_equivalents": "2,000"
  }
]

請將其視為算術問題。5 分鐘寫入的額外費用,在第一次呼叫時相當於 5,000 個 token:25,000,而未使用快取傳送該內容時則是 20,000。在快取有效期間,之後每次呼叫只計費 2,000,而不是 20,000,節省 18,000 個 token。因此,5 分鐘快取從第 2 次呼叫起便開始划算。

1 小時快取則是另一種取捨。寫入時會計費 40,000,相當於額外增加 20,000 個 token,因此必須在 1 小時內命中 2 次後才開始划算。這取決於您的流量模式,而不是模型本身。完整計算方式,以及如何選擇快取期限,請參閱 Claude prompt caching 的損益平衡計算

有兩個細節會決定您是否真的命中快取。首先,短於模型最低長度的前綴不會被快取,且系統不會顯示錯誤:截至 2026 年 8 月,文件記載的最低長度為 Claude Opus 5 的 512 個 token,以及 Claude Sonnet 5 的 1,024 個 token。較短的請求會正常處理,不會回傳錯誤。其次,快取生命週期是從寫入或讀取該項目的請求開始時起算,而且每次讀取都會在不增加費用的情況下更新期限。因此,忙碌的端點可以讓 5 分鐘快取無限期維持有效。每 10 分鐘才呼叫 1 次的端點,則每次都必須支付寫入的額外費用,卻始終無法取得快取讀取效益。

請檢查回應,不要只是假設快取已命中。usage 物件會回報 cache_creation_input_tokenscache_read_input_tokens。如果每次呼叫的讀取計數都是 0,表示您只支付了寫入費用,卻沒有取得任何回饋。

兩種快取的交會處

長系統提示詞是兩者的交會點,而且會同時從兩邊產生成本。

在本機端,20,000-token 的系統提示詞若使用 f16,在 Llama 3.1 8B 伺服器上約佔 2.4 GiB 的 KV cache;每個包含這段提示詞的並行請求,都會個別產生這項需求。在遠端端,同一個前綴只需寫入快取 1 次,之後每次呼叫的輸入成本為原本的 0.1 倍。本機成本會隨使用者數量增加;遠端成本會隨流量增加,並在閒置期間重設。

本機有一項功能看起來像供應商的提示詞快取,因此經常與其混淆:prefix caching。vLLM 文件將 automatic prefix caching 描述為快取「現有查詢的 KV cache,讓新查詢在與現有查詢之一共用相同前綴時,能直接重用該 KV cache」。llama.cpp server 預設會為每個 slot 保留 prompt cache,而 --cache-reuse N 會設定它嘗試重用的最小區塊大小。

prefix caching 能節省的是 prefill 計算量。20,000-token 的系統提示詞只需處理 1 次,不必在每個請求中重新處理,因此能大幅縮短第一個 token 的回應時間。在 vLLM 中,共用區塊會被重用,而不是重複建立,因此也能降低記憶體用量。但它不會縮減目前仍在使用中的 token 所需保留的快取容量。讓模型權重在請求之間保持載入,是相關但獨立的另一項調整方式,詳見 讓 Ollama 模型在請求之間保持載入

在自己的主機上測量的項目

以目標 context 載入模型,然後讀取實際數值,不要只相信估算結果。

ollama ps
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
free -g

ollama ps 會列出已載入的模型、模型大小,以及模型目前使用 GPU 或 CPU 執行。若原本預期模型能完整放入 GPU,但結果顯示部分內容分配到 CPU,表示 KV cache 將部分模型推到 GPU 外,生成速度也會隨之下降。nvidia-smi 會提供實際的 VRAM 數值;在僅使用 CPU 的 VPS 上,free -g 會提供相同用途的數值。逐步提高 context,每次重新載入模型,並觀察數值變化。自行計算的結果應與顯示數值接近。若兩者不一致,差距通常來自 runtime 自身使用的運算緩衝區,而不是公式錯誤。

如果這些數值讓你需要租用不想使用的硬體,請參閱 GPU VPS 與 API token 的比較,其中整理了按 token 付費的成本比較。

FAQ

KV cache 是否與 prompt caching 相同?

不是。KV cache 是 serving process 內部的每個請求專用記憶體,會保存目前內容中每個 token 的 key 和 value vectors。它位於 RAM 或 VRAM 中,請求結束時便會釋放。Provider prompt caching 是計費功能,會在 provider 的 infrastructure 上儲存穩定的 prompt prefix,之後再次傳送時採用較低費率。KV cache 耗盡會使模型無法載入。未命中 prompt cache 只會提高費用和 first token 的等待時間。

為什麼我的模型在 2k context 可以載入,卻在 32k 時失敗?

因為 runtime 會在載入時配置完整的 KV cache,其大小取決於你設定的 context length,而不是你實際傳送的 prompt。對於 f16 的 Llama 3.1 8B,cache 每個 token 需要 128 KiB,因此 2k context 需要 0.25 GiB,32k 則需要 4 GiB。兩種情況下 weights 都能容納。失敗的是記憶體保留。vLLM 會以 ValueError 回報此問題,指出它能儲存的最大 token 數量,並建議提高 gpu_memory_utilization 或降低 max_model_len。在僅使用 CPU 的主機上,則會由 kernel 的 out-of-memory killer 終止該 process;你可以使用 dmesg -T | grep -i "killed process" 確認。

如何計算模型的 KV cache 大小?

將 2 乘以 layer 數量、key/value head 數量、head dimension,以及每個 element 所占的 bytes。結果就是每個 token 所需的 bytes。接著乘以 context length,再乘以同時處理的請求數量。從模型的 config.json 讀取 layer 和 head 的數量。f16 或 bf16 每個 element 使用 2 bytes。q8_0 cache 約為上述大小的一半,q4_0 約為四分之一。

Prompt caching 會降低我自己的 server 所需的記憶體嗎?

Provider prompt caching 不會影響你的硬體,因為儲存空間位於 provider 端。本機的對應功能是 prefix caching,vLLM 和 llama.cpp server 都提供此功能。它會重用共用 prefix 已計算的 key 和 value vectors,節省 prefill 計算並縮短 first token 的等待時間。在 vLLM 中,共用 blocks 會被重用,而不是重複建立,因此也能改善記憶體使用量。這兩項功能都不會縮小目前執行中 token 所需的 cache,因此 context 與 concurrency 的計算仍會決定最低需求。

只傳送一次的 prompt 值得快取嗎?

不值得。截至 August 2026,cache write 的費用高於一般 input,5-minute 選項的費率是 base rate 的 1.25 倍。因此,如果 prefix 在該時間範圍內不會再次傳送,快取只會造成額外損失。當相同 prefix 會重複使用時,快取才有價值,例如較長的 system prompt,或你會針對其提出多個問題的文件。檢查 API response 中的 cache_read_input_tokens,確認是否命中 cache,而不是持續支付 write 費用。