值與靜默截?cái)嗟拇鷥r(jià))
本文摘要Ollama 默認(rèn)num_ctx為 4096長文檔超窗部分被靜默截?cái)嗪蟀攵螣o法引用。對(duì)比prompt_eval_count與預(yù)期 token 數(shù)即可發(fā)現(xiàn)截?cái)囡@式調(diào)大窗口即可修復(fù)。一、問題與結(jié)論可復(fù)現(xiàn)環(huán)境Ollama 0.11.4 模型llama3.2ollama show llama3.2 → context length 131072 接口POST http://localhost:11434/api/generate現(xiàn)象50 頁、約 11000 token 的工程規(guī)范 PDF問第 3 章前 10 頁能準(zhǔn)確引用條款號(hào)問第 7 章后 40 頁回答文檔中未提及或給出無關(guān)條款。接口返回done: true中間層與前端均未提示輸入被丟棄。根因num_ctx默認(rèn) 4096超出部分被靜默截?cái)嗪蠓祷伢w沒有truncated之類的告警字段模型基于殘缺上下文作答。二、排查與選擇依據(jù)判斷是否截?cái)嘀豢匆粋€(gè)字段prompt_eval_count——模型實(shí)際處理的輸入 token 數(shù)。# 1. 估算完整 prompt 的 token 數(shù)用 Ollama 自帶的分詞接口curl-shttp://localhost:11434/api/tokenize\-d{model:llama3.2,prompt:$(catlong_doc.txt)} \ | python3 -c import json,sys; print(tokens, len(json.load(sys.stdin)[tokens])) # 2. 默認(rèn)參數(shù)發(fā)請(qǐng)求 curl -s http://localhost:11434/api/generate \ -d {model:llama3.2,prompt:$(catlong_doc.txt) 第7章的驗(yàn)收標(biāo)準(zhǔn)是什么,stream:false}預(yù)期輸出tokens約 11000響應(yīng)中prompt_eval_count接近 4096。實(shí)際輸出tokens 11004 prompt_eval_count 4096 done true response 文檔中未提及該章節(jié)的驗(yàn)收標(biāo)準(zhǔn)。prompt_eval_count精確停在 4096done仍為true——這就是靜默截?cái)唷?096 11004差值 6908 token 全部丟失正好覆蓋文檔后 60%。常見失敗及修復(fù)把num_ctx設(shè)到 32768 后若prompt_eval_count仍停在 4096原因是請(qǐng)求體options拼寫錯(cuò)誤或被中間層丟棄或環(huán)境變量OLLAMA_CONTEXT_LENGTH未生效——修復(fù)方法是確認(rèn) JSON 中options.num_ctx存在或重啟 Ollama 時(shí)帶上OLLAMA_CONTEXT_LENGTH32768。替代方案與取舍方案選擇條件代價(jià)邊界本方案調(diào)大num_ctx單機(jī)、文檔 ≤ 數(shù)萬 tokenKV cache 隨窗口線性增長擠占顯存不得超過模型自身窗口RAG 分塊 top-k 檢索文檔遠(yuǎn)超窗口、多文檔知識(shí)庫需維護(hù)分塊與召回可能漏檢后半段答案依賴召回質(zhì)量換長上下文原生模型單文檔必須整段入窗重新 pull 模型推理顯存與延遲上升仍受顯存與模型上限約束Open WebUI 前端的 context 設(shè)置非開發(fā)者、輕量對(duì)話與 Ollama 側(cè)num_ctx是兩套獨(dú)立配置取兩者較小值界面調(diào)高不等于服務(wù)端生效不該用本方案的情況文檔量大到需要跨文檔檢索或顯存不足以支撐目標(biāo)窗口——此時(shí)應(yīng)走 RAG 分塊而不是硬拉num_ctx。三、關(guān)鍵原理KV cache 是每個(gè) token 的 K/V 張量緩存占用 ≈ 層數(shù) × 注意力頭數(shù) × 頭維度 × 2 × 每 token 字節(jié)數(shù) ×num_ctx。層數(shù)與頭維度由模型架構(gòu)固定因此占用與num_ctx近似線性。窗口翻 8 倍cache 也接近翻 8 倍這部分顯存從模型權(quán)重和生成批次里扣。截?cái)喟l(fā)生在 prompt 評(píng)估階段Ollama 按num_ctx截取輸入尾部丟棄再進(jìn)入預(yù)填充——后半段文檔從未參與注意力計(jì)算模型自然沒見過。四、可運(yùn)行示例環(huán)境本地已啟動(dòng) Ollama默認(rèn)端口11434已 pullllama3.2準(zhǔn)備一份long_doc.txt約 11000 token 的測(cè)試文檔。MODELllama3.2PROMPT$(catlong_doc.txt)第7章的驗(yàn)收標(biāo)準(zhǔn)是什么run(){curl-shttp://localhost:11434/api/generate\-d{\model\:\$MODEL\,\prompt\:\$PROMPT\,\stream\:false,\\options\:{\num_ctx\:$1,\num_predict\:256}}\|python3-cimport json,sys; rjson.load(sys.stdin); \ print(num_ctx$1prompt_eval_count , r[prompt_eval_count], \ answer , r[response][:80])}run4096run32768num_predict限制生成長度避免大窗口下輸出失控變慢。預(yù)期輸出兩次prompt_eval_count分別為 4096 與 11004第二次能引用第 7 章原文。實(shí)際輸出num_ctx4096 prompt_eval_count 4096 answer 文檔中未提及該章節(jié)的驗(yàn)收標(biāo)準(zhǔn)。 num_ctx32768 prompt_eval_count 11004 answer 第7.2條規(guī)定驗(yàn)收需在到貨后15個(gè)工作日內(nèi)...五、驗(yàn)證結(jié)果與邊界覆蓋范圍驗(yàn)證按文檔章節(jié)順序逐章提問統(tǒng)計(jì)能準(zhǔn)確引用原文的章節(jié)數(shù)。num_ctx4096時(shí)可答章節(jié)止于約第 3 章num_ctx32768時(shí)全部章節(jié)可答。兩者差異來自窗口而非模型能力。顯存增量窗口從 4096 提到 32768KV cache 增量 ≈ 8 倍的每 token 占用。具體 MB 數(shù)未在本機(jī)實(shí)測(cè)標(biāo)注為未驗(yàn)證建議用nvidia-smi或ollama ps在切換前后各采樣一次。按顯存分檔的參數(shù)建議可用顯存num_ctxnum_predict說明≤ 6 GB4096–8192512配合 RAG 分塊別硬拉窗口8–12 GB16384512單文檔長問答的常用檔≥ 16 GB32768256整段入窗注意生成延遲邊界num_ctx超過模型自身窗口會(huì)引發(fā)推理異常本節(jié)數(shù)值僅在llama3.2 Ollama 0.11.4 下驗(yàn)證其他模型未驗(yàn)證。參考資料ollama/ollamaopen-webui/open-webui