你下載的量化模型可能是壞的,而且 checksum 驗不出來

有人把 Ollama 官方庫 305 個程式碼模型全跑了一遍,發現 7 個低 bit 量化版幾乎全錯。但檔案沒有壞——重建回來 tensor 完全一致,所以 checksum 抓不到。這篇講它怎麼發生的、你現在能做的三件事。

7 分鐘Read in English
quantizationlocal-llmgguf
量化模型檔案完整但功能失效的示意圖,checksum 打勾、程式碼全錯

數字來自 arXiv 2609.05881v3 與作者的 quantcheck 稽核資料;「今天還在不在」是我們自己查的,腳本在文末。

先講一個畫面

你在筆電上 ollama pull qwen2.5-coder:3b,選了一個 2-bit 的版本,因為記憶體不夠。

模型跑起來了,有回應,速度也不錯。但你叫它寫一個排序函式,它寫出來的東西編譯不過;再試一題,還是不過。

你會先懷疑自己:prompt 寫錯?溫度太高?還是這顆模型本來就這麼弱?

有一篇論文把這個懷疑變成了普查:Ollama 官方庫裡 305 個「能寫程式」的模型 tag,有 7 個在 164 題 HumanEval+ 上幾乎全錯。 其中六個一題都沒對。

最反直覺的地方:檔案是好的

如果模型壞了,你會想「是不是下載壞了、檔案損毀」。

作者把其中五個檔案從原始權重重新量化回來,tensor 對 tensor 比對,完全一致。Qwen2.5-Coder-3B 那四個 tag,434 個 tensor 全部相同。

也就是說:這些檔案是「正確的壞檔案」。

checksum 會過、檔案大小會對、ollama show 看起來一切正常——因為檔案真的沒問題。壞的是量化的配方:同樣的權重、同樣的工具鏈、同樣的 tensor 組合,少了校準,就把模型壓成了不會寫程式的形狀。

為什麼會這樣

量化是「把權重從 16 bit 壓到 2–4 bit」。壓的過程要不斷決定「這個誤差要丟給哪個權重」。

預設的做法是均勻地丟;比較好的做法是看校準資料,把誤差集中在不重要的權重上——llama.cpp 的 importance matrix(imatrix)就是做這件事。

沒有 imatrix,小模型在低 bit 特別容易崩。這次的七個 suspects 全部落在 q2_K 到 q3_K_L、模型 ≤4B 這個範圍;同一個範圍有 48 個 tag,等於 14.6%。

但要注意:配方本身不能預測成敗。同樣的無校準配方,Qwen2.5-Coder-1.5B 的 q2_K–q3_K_L 全部正常(13–15 題)。所以不是「低 bit 一定壞」,是「壞了你不會知道」。

加回校準,救回大部分

作者固定權重、工具鏈與 tensor 組合,只補上 imatrix:

Tag原本補 imatrix 後(滿分 164)
Qwen2.5-Coder-3B q2_K0106–113
Qwen2.5-Coder-3B q3_K_M076–89
Qwen2.5-Coder-3B q3_K_L080–86
Qwen2.5-Coder-3B q3_K_S013–30(救不回)

(論文摘要寫「0 → 76–113」;上面是 v3.4 稽核資料的分級數字,我以資料為準。)

同一顆模型、同樣的位元數,只差一張校準表,從 0 題變成三位數。 這就是「量化不只是壓縮,是配方」的意思。

另一種壞法:少了 chat template

七個 suspects 之外,作者還測了 22 個 Hugging Face 社群檔案,其中兩個(TheBloke 的 deepseek-coder-6.7B Q3_K_M/Q4_K_M)在普查時只對 5、6 題。

原因不是量化,是檔案沒有附 chat template。Ollama 找不到 template,就用預設的 ChatML 去套,跟模型原本的指令格式不合——30 個回答裡有 28 個自己接出幻覺的對話輪。

補上正確 template 之後:98 與 101 題(滿分 164)。

所以「跑得起來」跟「它能好好回答」之間,還隔著一個 template。

我們今天查了:這些 tag 還在

文章不能只講九月的事。我們拿稽核資料裡的 blob digest,去比對 Ollama registry 今天的 manifest:

Tag稽核時的 digest今天狀態
qwen2.5-coder:3b-instruct-q2_K14c4247b8ce4…相同還在
qwen2.5-coder:3b-instruct-q3_K_S81d167af7fa3…相同還在
qwen2.5-coder:3b-instruct-q3_K_M9bb5d28b842a…相同還在
qwen2.5-coder:3b-instruct-q3_K_L7a88dc11faae…相同還在
phi3.5:3.8b-mini-instruct-q2_K54d47caa8bf3…相同還在
llama3.2:1b-instruct-q2_Kd1ede02a2111…相同還在
llama3.2:1b-instruct-q3_K_S81881dcc12ec…相同還在

七個都還在,digest 跟當時一模一樣。 這不是歷史事件,是你今天 ollama pull 就可能拿到的檔案。

(查法:https://registry.ollama.ai/v2/library/<model>/manifests/<tag>,比對 application/vnd.ollama.image.model 那層的 digest。腳本在文末。)

你現在該做的三件事

一、篩選。 作者釋出了 quantcheck:對每個 tag 跑 15 題螢幕測試。成本大約 30 秒生成(4090、不含下載)。66 個通過螢幕測試的重測,沒有一個是壞的——所以它是個堪用的預檢。

二、如果你自己發佈量化模型:補上 imatrix,然後在發佈前跑一次功能測試。registry 不會幫你測。

三、檢查 chat template。 ollama show <model> --template;如果印出 {{ .Prompt }},代表沒有 template,模型可能用錯格式回答。

別過度解讀

  • 2.3% 是「Ollama 官方庫、能寫程式、8GB 以下」這個子集的比例,不是所有量化模型
  • 只測程式碼能力(HumanEval+);perplexity 只能當預檢,不能當功能證明
  • 七個是下限:deepseek-coder-1.3B 全系列(含 fp16)都只對 1–6 題,無法用群組基線判定,作者沒有把它們算進去
  • 作者是獨立研究者,資料與工具都公開,但這是單一 registry、單一 runtime 版本的結果

結論

可重現,不等於可用。

檔案一致、checksum 通過、ollama show 正常——這些都只證明「檔案是你以為的那個檔案」,不證明「模型會做事」。

所以問題不是「量化能不能用」,是它有沒有被測過。目前答案是:registries 沒有,所以你得自己測。


原始資料:arXiv 2609.05881v3、quantcheck(稽核資料與工具)、Ollama issue #18252。

我們比對 digest 的腳本:scripts/check-ollama-tags.ts。跑 npm run check:ollama -- --list 會列出這七個 tag 今天的 digest 與稽核值是否一致。