重點速覽
本地大模型顯存需求約等於「權重大小+KV cache+執行時額外開銷」。權重大小用「參數量 × 每個權重平均位元數 ÷ 8」估算,KV cache 用層數、KV 頭數、每頭維度、上下文長度與每個元素的位元組數相乘,算出來再留約 1 GiB 餘裕,就能事先判斷放不放得下。
想知道手上的顯示卡跑不跑得動某個模型,關鍵在於估好本地大模型顯存:模型權重多大、對話越長 KV cache 多大、再加上執行時的額外開銷。這篇會把三項拆開,各給你一條可以自己代入數字的算式,最後整理成對照表和判斷步驟。讀完之後,你不需要先下載幾十 GB 的檔案才知道放不放得下。
為什麼顯存是第一道限制?
顯存(VRAM)是顯示卡上的專用記憶體,GPU 計算時要用的資料,最理想的情況是整份放在這裡。大型語言模型(LLM,大型語言模型,見術語表)稠密模型(每一層的所有權重都會參與運算的一般模型,和之後會談到的 MoE 相對)生成每一個字,都得用到全部的權重,所以權重放不進顯存,就只能放在相對慢的系統記憶體(llama.cpp 的多 GPU 說明就是這樣描述的),甚至根本載入失敗。
Hugging Face 的官方教學給過一條很直接的經驗法則:載入一個有 X 十億參數的模型,用 float32 大約需要 4 × X GB,用 bfloat16 或 float16 大約需要 2 × X GB。同一份教學也提到,輸入文字比較短(少於 1024 個 token)時,推論的記憶體需求主要由載入權重決定。token 是模型處理文字的最小單位,詳見術語表。
但文字一長,另一塊就會長大。所以完整的估算要拆成三項:
顯存需求 ≈ 權重大小 + KV cache + 執行時額外開銷
- 權重大小:模型本身的檔案內容,由參數量和量化方式決定。
- KV cache:推論時為每個已處理的 token 暫存的注意力 key/value,長度越長越大。
- 額外開銷:計算過程的暫存空間、多模態元件等,不同工具各不相同,只能留餘裕。
下面依序處理。為了避免單位混亂,本文一律用 GiB(1 GiB = 2^30 位元組,約 1.0737 × 10^9 位元組,這是算術換算)。工具或系統顯示的是 GB 還是 GiB 可能不同,兩者差約 7%,這也是估算要留餘裕的原因之一。
第一項:權重大小怎麼估?
量化(quantization)是把模型權重改用更少的位元儲存,讓模型變小。它的完整原理和各種格式的差別放在量化是什麼,這裡只需要一個結論:每個量化格式都有一個「每個權重平均用幾個位元」的數字,叫做 bits per weight(bpw)。有了它,權重大小就是一道簡單的乘除:
權重大小(位元組)= 參數量 × 平均每個權重的位元數 ÷ 8
權重大小(GiB) = 上式 ÷ 2^30
- 參數量:模型有幾個權重,例如「8B」就是 8 × 10^9 個。
- 平均位元數:量化格式決定。除以 8 是因為 1 位元組有 8 個位元。
各量化格式的平均位元數
llama.cpp 的量化工具說明,以 Llama-3.1-8B 為例,列出了每種量化的 bits/weight 和檔案大小。下表摘出常用的幾種(數字照原表):
| 量化格式 | bits/weight(Llama-3.1-8B) | 檔案大小(GiB,原表) |
|---|---|---|
| Q2_K | 3.1593 | 2.95 |
| Q3_K_M | 3.9960 | 3.74 |
| Q4_K_M | 4.8944 | 4.58 |
| Q5_K_M | 5.7036 | 5.33 |
| Q6_K | 6.5633 | 6.14 |
| Q8_0 | 8.5008 | 7.95 |
| F16 | 16.0005 | 14.96 |
這張表有兩件事要注意。第一,平均位元數都比名字裡的數字高一點,例如 Q4_K_M 的平均是 4.8944 而不是 4。原因在於量化工具預設會用「k-quant 混合」,不同的張量(tensor,模型內的一塊權重矩陣)用不同的量化類型;官方的選項說明裡有 --pure,作用就是關掉這種混合、讓所有張量用同一種類型。第二,這張表是針對 Llama-3.1-8B 量出來的,換一個模型,各層組合不同,平均位元數會有些差異,所以這裡拿它當估算用的近似值。
用原表驗算公式
量化說明的另一張表把 Llama 3.1 的「8B」模型的原始大小(F32)寫成 32.1 GB。F32 每個權重 4 位元組,所以參數量約為:
示範計算:
參數量 ≈ 32.1 × 10^9 ÷ 4 ≈ 8.025 × 10^9
Q4_K_M 權重 ≈ 8.025 × 10^9 × 4.8944 ÷ 8 ≈ 4.91 × 10^9 位元組
≈ 4.91 × 10^9 ÷ 1.0737 × 10^9 ≈ 4.57 GiB
原表寫的是 4.58 GiB,和算出來的 4.57 差在四捨五入內。也就是說,公式沒有問題,只要把參數量和平均位元數代進去就行。
第二項:KV cache 怎麼估?
它存了什麼
語言模型是一個字一個字往後生成的,每預測下一個 token,都需要前面所有 token 的資訊。Hugging Face 的說明這樣描述:KV cache 把前面已處理 token 在注意力層算出來的 key 和 value 存起來,之後直接取用,不必重算。它是每一層各存一份,並且每處理一個新 token,就把新的 key/value 接在後面,所以序列越長,快取就越大;文件也提到這個快取只用在推論,不用在訓練。
這就是為什麼同一個模型,對話越長,顯存用得越多。上下文長度(context window,模型一次能參考的 token 數,見術語表)拉長一倍,KV cache 也跟著大約增加一倍。llama.cpp 的多 GPU 說明在談 OOM(顯存不足)時,也把「KV cache 大致和 n_ctx 成正比」當成調整的依據。
公式
KV cache(位元組)
= n_layer × n_ctx × n_head_kv × (key_length + value_length) × bytes_per_element
n_layer:層數(區塊數)。每一層各有一份快取。n_ctx:你實際設定的上下文長度(token 數),不是模型最大支援的長度。n_head_kv:key/value 的頭數。key_length、value_length:每個 key 頭、value 頭的維度。多數情況下兩者相同,統稱「每頭維度」,所以括號內也可寫成 2 × 每頭維度(2 代表 key 和 value 各一份)。bytes_per_element:每個數字佔幾位元組。llama.cpp 伺服器說明列出 KV cache 的資料類型預設是 f16,也就是 16 位元,等於 2 位元組。
這個算式和 Transformers 教學裡的算式是同一回事:該教學寫「要存的浮點數個數 = 2 × 序列長度 × 注意力頭數 × 每頭維度 × 層數」,並用它的示範模型在 16000 個 token 時算出約 80 億個數字,以 float16 儲存約 15 GB,大約是模型權重的一半。
為什麼是「KV 頭數」而不是「注意力頭數」
那份教學後面接著說明了兩種減少 KV cache 的架構:多查詢注意力(MQA)讓所有注意力頭共用一組 key/value,分組查詢注意力(GQA,Grouped-Query Attention)則是用比注意力頭數少的 n 組 key/value(文件舉的例子是 2、4 或 8 組),保留了 MQA 大部分的記憶體與速度好處。文件也寫道:若模型要處理很長的輸入,例如聊天,強烈建議使用 GQA 或 MQA。
所以公式裡要用「KV 頭數」。同樣是 32 個注意力頭的模型,有沒有用 GQA,KV cache 可以差好幾倍(見下面的示範)。
公式裡的數字去哪查?GGUF metadata
GGUF 是 ggml 生態系使用的模型檔案格式,一個檔案就包含載入模型所需的所有資訊。它用「鍵值對」的 metadata 儲存超參數。GGUF 規格定義了下列欄位([llm] 代表架構名稱,例如 llama):
| 公式中的量 | GGUF metadata 欄位 | 規格上的說明 |
|---|---|---|
| n_layer | [llm].block_count | 注意力加前饋層的區塊數,不含輸入與嵌入層 |
| n_head_kv | [llm].attention.head_count_kv | 不存在,或等於 head_count 時,表示模型沒有使用 GQA(此時 KV 頭數就是 head_count) |
| key_length | [llm].attention.key_length | 選填;未指定時等於 embedding_length ÷ head_count |
| value_length | [llm].attention.value_length | 選填;未指定時等於 embedding_length ÷ head_count |
| 模型最大上下文 | [llm].context_length | 模型訓練時的上下文長度;多數架構以此為輸入的硬上限 |
補充一個容易卡住的地方:規格對 head_count_kv 的英文描述是 “the number of heads per group used in Grouped-Query-Attention”,字面有點拗口,但它緊接著的判斷規則是「不存在或等於 head_count 就代表沒有用 GQA」,這只有把它讀成「KV 頭數」才說得通,所以公式裡的 n_head_kv 就是它。
也就是說,你不需要憑印象猜層數和頭數,這些數字是模型自己帶著的。至於用哪個工具把 metadata 印出來,各家介面不同,這裡不寫步驟,請查你所用工具的說明。另外,不同架構可能多出額外的欄位,實際以你手上那個模型檔案為準。
示範計算:假設的模型
以下是完全假設的模型,數字是為了好算而編的,不是任何真實模型的規格:
假設模型 A:
n_layer = 32
n_head_kv = 8
key_length = value_length = 128
bytes_per_element = 2(f16)
n_ctx = 8192:
32 × 8192 × 8 × (128 + 128) × 2
= 1,073,741,824 位元組 = 1 GiB
n_ctx = 32768(長度變 4 倍):
32 × 32768 × 8 × 256 × 2 = 4 GiB
若同一模型沒用 GQA,n_head_kv = 32(n_ctx = 8192):
32 × 8192 × 32 × 256 × 2 = 4 GiB
另一個假設模型 B(n_layer = 64,其餘同 A)、n_ctx = 8192:
64 × 8192 × 8 × 256 × 2 = 2 GiB
從這個算例可以看到:上下文長度 ×4,KV cache 就 ×4;KV 頭數多 4 倍,KV cache 也多 4 倍;層數多一倍,KV cache 也多一倍。
估算會偏高的情況
有些模型不是每一層都存完整長度的快取。Transformers 的 KV cache 說明提到,使用滑動視窗注意力(sliding window attention)或分塊注意力(chunked attention)的模型,那些層的快取長到視窗或區塊大小就不再增加。遇到這類模型,用上面公式算出來的值會偏保守,偏高總比偏低安全。
KV cache 的資料類型可以改
llama.cpp 伺服器說明列出 --cache-type-k 與 --cache-type-v 兩個選項,可選的類型包括 f32、f16、bf16、q8_0、q4_0 等,預設為 f16。也就是說,KV cache 的位元數是獨立於權重量化設定的。把它換成位元數較少的類型,公式裡的 bytes_per_element 就變小,但官方並沒有在那份說明裡說明對輸出品質的影響,所以要不要這樣做,請自己驗證。選項名稱與可用值會隨版本變動,以官方說明為準。
第三項:額外開銷要留多少?
額外開銷是三項裡最難精準估算的,因為它取決於你用的工具和設定。官方說明能確認的是這幾點:
- 留餘裕是工具自己的做法。 llama.cpp 的
--fit預設是開啟的,會自動調整你沒指定的參數讓模型放進裝置記憶體,而且--fit-target(每個裝置保留的餘裕)預設是 1024 MiB。本文的示範採用一樣的數量級:至少保留 1 GiB。 - 同時處理的對話數也算。 llama.cpp 的多 GPU 說明提到,llama-server 每個同時進行的序列會各配置一份 KV cache,所以要降低顯存壓力,可以降低
--parallel。 - 多模態元件也會佔位置。 llama.cpp 的多模態說明寫到,多模態投影器(mmproj)預設會被放到 GPU 上;如果你載入的是能看圖的模型,這一份要另外算。
- 注意力計算本身也有暫存空間。 Transformers 的教學說明,標準自注意力在運算時的峰值記憶體會隨輸入長度平方成長,而 Flash Attention 可以讓記憶體成本只隨長度線性增加。實際用了哪種實作,取決於工具與設定。
另一個容易混淆的地方是:llama.cpp 的 -c(上下文長度)預設是 0,代表「從模型讀取」,也就是可能直接取模型訓練時的長度;而在 --fit 開啟時,伺服器說明提到載入的實例會取「載入當下放得下的最大上下文」。換句話說,如果你沒有自己指定,看到顯存被吃得很滿,不代表模型權重本身那麼大,可能只是工具把剩下的空間拿去放更長的上下文。你想要精準控制時,就自己設定上下文長度。這些預設值屬於會變的細節,以官方說明為準。
比較表一:模型大小 × 量化 → 權重所需 GiB
下表是純算術的示範計算:參數量取整數(單位 10^9),平均位元數取上面的 Llama-3.1-8B 表,套用「參數量 × bpw ÷ 8 ÷ 2^30」。它不代表任何特定模型的實際檔案大小,真實檔案會因架構和量化組合而略有不同。
| 參數量 | Q3_K_M | Q4_K_M | Q5_K_M | Q6_K | Q8_0 | F16 |
|---|---|---|---|---|---|---|
| 4B | 1.9 | 2.3 | 2.7 | 3.1 | 4.0 | 7.5 |
| 8B | 3.7 | 4.6 | 5.3 | 6.1 | 7.9 | 14.9 |
| 14B | 6.5 | 8.0 | 9.3 | 10.7 | 13.9 | 26.1 |
| 32B | 14.9 | 18.2 | 21.2 | 24.5 | 31.7 | 59.6 |
| 70B | 32.6 | 39.9 | 46.5 | 53.5 | 69.3 | 130.4 |
單位:GiB,只含權重。要放進顯存,這個數字之外還要再加 KV cache 和餘裕。
比較表二:我的顯存大約能放多大的模型?
下一張表把方向反過來:已知顯存,問「權重預算」有多少,再反推最大參數量。這張表有兩個假設前提,請務必看清楚:
- KV cache 取上面「假設模型 A、上下文 8192」的 1 GiB。
- 額外開銷取 1 GiB 的餘裕。
所以權重預算 = 顯存 − 1 − 1 = 顯存 − 2(GiB)。最大參數量 = 權重預算 × 2^30 × 8 ÷ bpw。
| 顯存容量(GiB) | 權重預算(GiB) | Q3_K_M | Q4_K_M | Q6_K | Q8_0 |
|---|---|---|---|---|---|
| 6 | 4 | 8.6B | 7.0B | 5.2B | 4.0B |
| 8 | 6 | 12.9B | 10.5B | 7.9B | 6.1B |
| 12 | 10 | 21.5B | 17.6B | 13.1B | 10.1B |
| 16 | 14 | 30.1B | 24.6B | 18.3B | 14.1B |
| 24 | 22 | 47.3B | 38.6B | 28.8B | 22.2B |
這是示範計算,不是保證。你的模型如果層數更多、沒用 GQA,或你要的上下文更長,KV cache 就會超過 1 GiB,表中的數字要往下調;反過來,上下文很短時,才有往上的空間。另外它只適用於「全部權重都放進顯存」的稠密模型;混合專家模型要看下一節。
判斷放不放得下的步驟
- 查你能用的顯存。 看顯示卡的顯存總容量,再扣掉其他程式正在佔用的部分。把單位統一成 GiB。
- 決定要看的模型與量化。 取得參數量,以及你想用的量化格式。直接看 GGUF 檔案大小最準,因為那就是權重;沒有的話,用「參數量 × bpw ÷ 8」估算。
- 決定你實際要用的上下文長度。 不要用模型的最大值,用你真的需要的。一般聊天和讀長文件需求差很多。
- 讀出 KV 公式要用的數字。 從 GGUF metadata 找
block_count、attention.head_count_kv(沒有就用head_count)、key_length與value_length(沒有就用embedding_length ÷ head_count)。 - 算 KV cache。 代入公式:
n_layer × n_ctx × n_head_kv × (key_length + value_length) × bytes_per_element,f16 時 bytes_per_element 為 2。 - 加總並留餘裕。 權重 + KV cache + 至少 1 GiB 餘裕。如果有多模態元件或同時多個對話,也要分別加上去。
- 比較。 總和小於你的可用顯存,就放得下;小一點不多就是勉強,建議降低上下文或換更小的量化。
完整示範:同一個假設模型,在兩種顯存下的判斷
假設有一個 8B 的稠密模型(8 × 10^9 個參數),KV 部分用上面的假設模型 A(8192 上下文時為 1 GiB),餘裕 1 GiB:
Q4_K_M 權重 = 8 × 10^9 × 4.8944 ÷ 8 ÷ 2^30 ≈ 4.56 GiB
總需求 ≈ 4.56 + 1 + 1 = 6.56 GiB
顯存 8 GiB:6.56 < 8 → 放得下,剩約 1.4 GiB
顯存 6 GiB:6.56 > 6 → 放不下
6 GiB 時的調整方案:
(a) 上下文減半到 4096:KV ≈ 0.5 GiB → 4.56 + 0.5 + 1 = 6.06 GiB,仍略大於 6
(b) 改 Q3_K_M:權重 = 8 × 10^9 × 3.9960 ÷ 8 ÷ 2^30 ≈ 3.72 GiB
8192 上下文:3.72 + 1 + 1 = 5.72 GiB → 小於 6,但只剩約 0.28 GiB,很緊
4096 上下文:3.72 + 0.5 + 1 = 5.22 GiB → 較有餘裕
這個算例也說明為什麼要同時看三項:光看「Q4_K_M 的檔案只有 4.6 GiB,6 GiB 的顯存放得下」會誤判。
放不下時有哪些選項?
大致照「代價由小到大」排列:
- 縮短上下文。 對 KV cache 影響最直接,因為它和長度大致成正比。llama.cpp 的多 GPU 說明在談顯存不足(OOM)時,也是依「破壞性由小到大」排列,第一項就是降低
--ctx-size。(它談的是多 GPU 的情境,這裡借用它的排序來說明各選項的代價。)代價是模型一次能參考的內容變少。 - 減少同時處理的對話數。 如果你用伺服器模式開了多個並行序列,每個序列都有各自的 KV cache,降低並行數可以直接省下顯存。
- 換更小的量化。 例如從 Q6_K 降到 Q4_K_M,權重大小按表一直接縮小,代價是精度損失可能變大。量化工具的官方說明明白寫著,量化「可能帶來一些精度損失」。各格式的差別與取捨請看量化是什麼。
- 把部分層放到系統記憶體。 llama.cpp 的專案簡介列了「CPU+GPU 混合推論」,讓大於顯存的模型可以部分加速;伺服器說明裡的
--n-gpu-layers決定最多幾層放進顯存。但官方也提醒,被放在 CPU 上執行的層,推論會慢很多。顯存、記憶體和硬碟各自的分工,請看顯存、記憶體、硬碟各扮演什麼角色。 - 改用混合專家(MoE)模型。 但要注意它不是「便宜的大模型」,詳見下一小節。
- 換成參數量更小的模型。 最直接,但能力也跟著下降。
這些做法對速度的影響,只能定性說:多數情況下,越多東西被擠出顯存,生成速度越慢。怎麼正確地量速度、怎麼讀 tokens/s,請看 Token/s 怎麼看與正確的速度測試方法。
MoE 模型的顯存怎麼估
混合專家(Mixture of Experts,MoE)模型把前饋層拆成多個「專家」,每個 token 只會啟用其中幾個。細節在MoE 混合專家模型,這裡只談對顯存的影響。Transformers 的 Mixtral 說明給了很清楚的例子:Mixtral 有 8 個專家,總參數量是 450 億,但單次前向運算所需的計算量和一個 140 億參數的模型相當,因為每個 token 只分配給兩個專家;不過文件同時指出,所有專家都需要載入記憶體。
所以估權重時要用總參數量,不是啟用的參數量:速度比較像小模型,但權重大小要照整個模型算。llama.cpp 的伺服器說明另有 --cpu-moe 與 --n-cpu-moe 選項,作用是把 MoE 的專家權重留在 CPU 端;這是把「放不下的部分」交給系統記憶體的一種做法,同樣屬於會變的參數名稱,以官方說明為準。
工具範例
如果你想看到實際的工具如何在顯存有限的電腦上載入大模型,可以參考Strata vs PolyStrata 差別比較,該篇依顯示卡等級介紹了兩個本地大模型工具的選擇。
常見誤解
誤解一:把系統記憶體當顯存。 「我的記憶體有 32GB,所以可以跑 30GB 的模型」是常見的誤判。系統記憶體當然能放得下檔案,但 GPU 並不會直接用它計算;llama.cpp 官方的說法是,混合推論只能「部分加速」大於顯存的模型,而留在 CPU 的層會慢很多。有些工具的需求規格會用「RAM 加顯存合計」來表示(本站的 Strata vs PolyStrata 比較就是這樣列的),那代表的是「載得進去」,不等於「跑得快」。
誤解二:只看檔案大小。 檔案大小只回答了權重那一項。同一個模型,上下文設 4096 和設 32768,KV cache 可以差好幾 GiB(見前面的示範)。
誤解三:忽略上下文長度。 模型說明頁寫的「支援幾 K 上下文」,在 GGUF 規格裡對應的是 context_length,意思是模型訓練時的上下文長度,是輸入的上限,不是你必須使用的長度。你設多長,KV cache 就依多長配置。
誤解四:顯存被吃滿,就代表模型很大。 前面說過,有些工具在你沒指定時,會把剩餘空間拿去放更長的上下文。要判斷模型本身的需求,看權重和你指定的 KV cache,而不是看工具或系統顯示的顯存使用量。
誤解五:選了 Q4 的模型,KV cache 也跟著變 4 bit。 權重量化和 KV cache 的類型是兩個獨立的設定,KV cache 預設是 f16。
誤解六:算得進去就一定順暢。 估算只回答「放不放得下」。放得下之後的速度,還取決於其他因素(例如記憶體頻寬與你用的工具);餘裕太小時,只要多開一個程式或把上下文拉長一點,就可能出現顯存不足。
延伸閱讀
- 量化是什麼(Q4、Q8、GGUF):每個量化格式的取捨,以及怎麼選。
- 顯存、記憶體、硬碟各扮演什麼角色:放不下時,系統記憶體和硬碟能幫到哪裡。
- MoE 混合專家模型:為什麼總參數量大、速度卻不一定慢。
- Token/s 怎麼看與正確的速度測試方法:放得下之後,怎麼正確評估速度。
- Strata vs PolyStrata 差別比較:兩個本地大模型工具如何配合不同大小的顯示卡。
- 術語表:token、上下文視窗、LLM 等名詞的簡短定義。
常見問題
本地跑大模型至少要多少顯存?
沒有固定答案,要看模型大小、量化和上下文長度。估算方式是「權重+KV cache+額外開銷」:權重 ≈ 參數量 × 每個權重平均位元數 ÷ 8,例如 8B 模型用 Q4_K_M 約 4.6 GiB(示範計算),再加上 KV cache 和約 1 GiB 的餘裕,就是你至少要準備的顯存。
顯存不夠的話,可以用系統記憶體補嗎?
可以,但會變慢。llama.cpp 官方說明有 CPU+GPU 混合推論,讓大於顯存的模型也能執行,但留在 CPU 上執行的層,官方也說明推論會慢很多。系統記憶體是補救手段,不等於顯存。
上下文長度會多吃多少顯存?
KV cache 的大小大致和上下文長度成正比(llama.cpp 官方說明的說法是 roughly proportional)。以文中假設的 32 層、8 個 KV 頭、每頭 128 維、f16 的模型為例,8192 tokens 約 1 GiB,32768 tokens 約 4 GiB(示範計算)。
KV cache 是什麼?為什麼會佔顯存?
KV cache 是推論時為每個已處理的 token 暫存的注意力 key/value,讓模型不必每生成一個字就重算前面所有內容。它要為每一層、每個 KV 頭都存一份,所以上下文越長、層數越多,佔的顯存就越大。
Q4_K_M 一個權重平均用幾 bit?
llama.cpp 量化說明以 Llama-3.1-8B 為例,列出 Q4_K_M 的平均值是 4.8944 bits/weight,Q8_0 是 8.5008,F16 是 16.0005。這是以該模型為例的表,其他模型各層的量化組合不同,數字會略有差異,所以拿來估算要留餘裕。
要去哪裡查模型的層數和 KV 頭數?
這些數字寫在模型 GGUF 檔案的 metadata 裡。GGUF 規格定義了 block_count(層數)、attention.head_count、attention.head_count_kv(KV 頭數)等欄位;用能讀取 GGUF metadata 的工具就能查到,不需要自己猜。
留言
用 GitHub 帳號登入就能留言,留言會公開顯示在 GitHub Discussions。留言前請先看社群規則。