Agent本地部署指南:從模型量化到Ollama實(shí)戰(zhàn))
這兩年端側(cè) Agent 的熱度一直沒降和以往那種“云上大腦”的做法不同現(xiàn)在越來越多人想把整個(gè)鏈路壓到一塊本地設(shè)備上。我自己也花了很長時(shí)間折騰各種開發(fā)板和推理框架最后發(fā)現(xiàn)真正決定體驗(yàn)的往往不是哪家模型跑分多高而是部署時(shí)你有沒有把硬件、量化、上下文和 Agent 調(diào)度這幾件事想清楚。這篇文章就以端側(cè) LLM 部署為主線從硬件選型講到 Ollama 實(shí)操再接到 Agent 接入盡量把關(guān)鍵環(huán)節(jié)的原理和坑都拆開說。適合正在做本地智能體的開發(fā)者也適合手里有 RK3588、Jetson Orin 等設(shè)備的硬件玩家參考。1. 端側(cè) LLM 部署到底在解決什么問題1.1 先弄明白“端側(cè) Agent”要什么端側(cè) Agent 和云端 Agent 最大的區(qū)別是它所有的關(guān)鍵模塊都在本地。一個(gè)完整 Agent 通常需要大模型提供語言理解、規(guī)劃、工具調(diào)用和記憶歸納能力但本地設(shè)備不是數(shù)據(jù)中心內(nèi)存和算力都有限所以端側(cè) Agent 實(shí)際要的是一個(gè)“夠用且可控”的推理底座。夠用指的是模型能理解復(fù)雜一點(diǎn)的指令能調(diào)用工具能記住對話上下文可控則意味著模型權(quán)重、運(yùn)行參數(shù)、推理緩存都在自己手里不依賴外部服務(wù)也不會因?yàn)榉?wù)波動導(dǎo)致整套系統(tǒng)癱瘓。這也就引出了端側(cè) LLM 部署的核心價(jià)值。首先是隱私個(gè)人數(shù)據(jù)、辦公文檔、攝像頭畫面這些敏感信息不需要離開設(shè)備Agent 可以全部在本地完成理解與處理。其次是確定性你部署的模型版本、量化參數(shù)、上下文長度完全由自己掌控不會出現(xiàn)云端模型偷偷換版本導(dǎo)致行為漂移的問題。最后是延遲端側(cè)推理省去了網(wǎng)絡(luò)往返一次工具調(diào)用的判斷從幾百毫秒壓縮到幾十毫秒這種低延遲對機(jī)器人控制、實(shí)時(shí)交互類 Agent 尤其重要。但這三個(gè)價(jià)值不是白來的。端側(cè)模型因?yàn)轶w積受限通用知識儲備和復(fù)雜推理能力通常弱于云端大模型所以你在設(shè)計(jì)端側(cè) Agent 時(shí)必須主動縮小任務(wù)范圍把復(fù)雜任務(wù)拆成多個(gè)小步驟用外部工具補(bǔ)足模型能力。不要在 7B 模型上強(qiáng)行做一個(gè)什么都能聊的通用助手而是要讓它老老實(shí)實(shí)當(dāng)好“調(diào)度員”和“解析器”。1.2 三座大山內(nèi)存、算力、功耗做過端側(cè)部署的人都知道真正卡脖子的不是模型算法有多難而是硬件層面那三個(gè)硬指標(biāo)內(nèi)存、算力、功耗。內(nèi)存決定模型上限。部署一個(gè) 7B 參數(shù)模型即使是 Q4 量化光權(quán)重就要占 4GB 左右推理時(shí)還要額外預(yù)留 KV Cache 和臨時(shí)計(jì)算空間16GB 內(nèi)存的設(shè)備跑 7B 模型基本就是“剛好夠用”。內(nèi)存不夠時(shí)模型根本加載不進(jìn)去或者被系統(tǒng)換入換出速度慢到無法接受。算力決定體驗(yàn)下限。這里的算力不能只看 INT8 峰值還要看內(nèi)存帶寬。模型推理本質(zhì)上是反復(fù)讀取參數(shù)權(quán)重做矩陣乘法如果內(nèi)存帶寬只有 30GB/s那 4.5GB 權(quán)重讀一遍就要 0.15 秒理論上每秒生成上限也就 6-7 個(gè) Token。很多板子參數(shù)表寫得很唬人真跑起來卻像老牛拉車問題多半就出在帶寬上。功耗則決定應(yīng)用場景。開發(fā)板放在桌面上一直插電無所謂但如果 Agent 要裝到無人機(jī)、機(jī)械臂、AGV 小車?yán)锕暮桶l(fā)熱就是硬約束必須犧牲一部分性能換取續(xù)航。1.3 部署不是“把模型裝上去”那么簡單很多人第一次接觸端側(cè) LLM 部署以為就是下載一個(gè)模型文件丟到板子里然后跑個(gè)推理腳本。實(shí)際做下來你會發(fā)現(xiàn)端側(cè) LLM 部署是四層工程的疊加模型壓縮、格式轉(zhuǎn)換、推理運(yùn)行時(shí)、服務(wù)封裝。模型壓縮指量化、蒸餾、剪枝這些手段目的是把模型體積壓到硬件能接受的范圍格式轉(zhuǎn)換決定模型以什么形態(tài)存儲和加載比如 GGUF 格式對部署最友好推理運(yùn)行時(shí)負(fù)責(zé)把模型高效地調(diào)度到底層芯片上執(zhí)行服務(wù)封裝則是向外提供標(biāo)準(zhǔn) API讓 Agent 框架可以穩(wěn)定調(diào)用。四層缺一不可任何一層不匹配后面 Agent 接進(jìn)來就會出現(xiàn)亂碼、超時(shí)、工具調(diào)用失敗這些稀奇古怪的問題。所以我把部署看作一個(gè)系統(tǒng)性的“適配工程”而不是單點(diǎn)操作。后面所有內(nèi)容都圍繞這四層展開。2. 硬件選型先算賬再動手2.1 內(nèi)存決定模型上限算力決定體驗(yàn)下限選硬件最常犯的錯(cuò)誤是只看“能不能跑 GPT 級別的模型”我建議反過來先確定你的 Agent 需要什么規(guī)模的模型再倒推硬件配置。比如你要做的是本地知識庫問答那 7B 模型加 RAG 方案就夠如果要跑視覺語言 Agent不僅要考慮語言模型還要考慮視覺編碼器占用的額外資源內(nèi)存預(yù)算要往上調(diào)。有了目標(biāo)模型規(guī)模后用經(jīng)驗(yàn)公式算內(nèi)存占用模型文件大小 上下文緩存 系統(tǒng)開銷。7B 模型 Q4 量化后文件約 4.7GB如果上下文開 8192KV Cache 大約要額外 1-2GB再加上操作系統(tǒng)和 Agent 運(yùn)行時(shí)16GB 設(shè)備實(shí)際可用內(nèi)存最好不少于 8GB否則會很吃緊。算力方面則要關(guān)注推理加速單元的實(shí)際效果。Jetson 上的 GPU 和 CUDA 生態(tài)適配成熟llama.cpp、Ollama 都能直接利用RK3588 的 NPU 峰值很高但部署工具鏈相對碎片化很多時(shí)候你在板子上跑的還是 CPU 推理實(shí)際速度和標(biāo)稱 TOPS 完全是兩回事。所以我建議把“實(shí)測 token/s”作為核心選型指標(biāo)而不是跑分表。2.2 兩張主流開發(fā)板的配置盤點(diǎn)我自己用得最多的是 Jetson Orin 系列和 RK3588 系列這兩類板子在端側(cè) Agent 圈子里討論度最高也最值得對比。Jetson Orin NX 16GB 是目前跑端側(cè) Agent 比較舒服的“甜點(diǎn)位”。它有 16GB LPDDR5 內(nèi)存GPU 算力足夠支撐 7B 甚至 14B 量化模型而且 CUDA 生態(tài)成熟絕大多數(shù)推理框架都是開箱即用。我做多模態(tài) Agent 時(shí)視覺編碼器加語言模型加載進(jìn)去還能剩不少緩沖。缺點(diǎn)是價(jià)格貴而且散熱做好以后體積還是偏大。RK3588 則是性價(jià)比路線的代表。常用版本板載 8GB 或 16GB 內(nèi)存CPU 性能不錯(cuò)內(nèi)置 NPU 在特定算子下能干活但模型部署時(shí)經(jīng)常遇到算子兼容問題。我在 RK3588 上跑通 7B 量化模型更多是靠 CPU 推理速度比 Jetson 慢不少但它勝在便宜、接口豐富、功耗低適合做邊緣網(wǎng)關(guān)類 Agent 或嵌入式原型驗(yàn)證。2.3 選型參數(shù)對比表為了讓你一眼看清定位差異我整理了一張常用設(shè)備對比表按我實(shí)際體驗(yàn)標(biāo)注價(jià)格會隨行情波動僅供參考。設(shè)備內(nèi)存有效算力推薦模型規(guī)模參考價(jià)格適用場景Jetson Orin NX 16GB16GB LPDDR5較強(qiáng) GPU7B~14B 量化6000-8000元機(jī)器人、多模態(tài) Agent、高質(zhì)量對話Jetson Orin Nano 8GB8GB LPDDR5入門 GPU1.5B~4B 量化2000元左右入門驗(yàn)證、輕量 AgentRK3588 16GB16GB LPDDR4x6 TOPS NPUCPU4B~7B 低量化1300-2500元工控、邊緣盒子、嵌入式原型Apple Silicon 16GB16GB 統(tǒng)一內(nèi)存高帶寬 GPU7B~14B 量化二手約5000元本地辦公助手、開發(fā)調(diào)試?yán)峡?NUC 16GB16GB 雙通道核顯較弱7B 低量化2000-3000元服務(wù)器式常駐 Agent 服務(wù)選型時(shí)還有一個(gè)容易忽略的點(diǎn)內(nèi)存通道數(shù)。單通道內(nèi)存帶寬減半對推理速度的拖累非常明顯所以盡量選雙通道或統(tǒng)一內(nèi)存架構(gòu)的設(shè)備。跑同一個(gè)小模型我在雙通道設(shè)備上見過 2 倍的差距。3. 模型量化與格式轉(zhuǎn)換3.1 量化原理用一點(diǎn)精度換運(yùn)行可能量化這個(gè)詞聽起來很高級其實(shí)就是把模型里的浮點(diǎn)數(shù)權(quán)重從 16 位或 32 位壓縮到 8 位、4 位用更少的比特表示同一個(gè)參數(shù)。你可以理解成把一本高清畫冊壓縮成網(wǎng)頁縮略圖內(nèi)存占用量直線下降畫質(zhì)有損失但大多數(shù)圖還是能認(rèn)得出來。對端側(cè)來說量化直接決定你能不能跑得起某個(gè)模型。同樣一個(gè) 7B 模型FP16 格式要占 14GB 左右絕大多數(shù)開發(fā)板直接勸退轉(zhuǎn)成 Q4 量化后只需要 4-5GB16GB 內(nèi)存設(shè)備就完全有機(jī)會跑起來。差別不是性能好壞而是“能不能開機(jī)”。不過量化帶來的精度損失在 Agent 場景里會被放大。小模型經(jīng)過量化后指令遵循能力會下降可能出現(xiàn) JSON 輸出格式不穩(wěn)定、工具參數(shù)生成缺失、甚至完全忽略系統(tǒng)提示詞的情況。所以我不建議一上來就使用壓縮最狠的量化等級而是要留出余量。如果設(shè)備內(nèi)存允許Q5、Q8 的穩(wěn)定性通常會好一截。3.2 GGUF 與 llama.cpp 生態(tài)做端側(cè)部署基本繞不開 GGUF 格式它是 llama.cpp 項(xiàng)目推出的模型封裝格式。GGUF 把模型權(quán)重、分詞器、超參數(shù)、甚至自定義的聊天模板都打包進(jìn)一個(gè)文件里部署時(shí)只要加載這一個(gè)文件就能跑不需要分別處理權(quán)重和配置大大降低了集成成本。更關(guān)鍵的是 GGUF 支持分段保存和內(nèi)存映射。分段保存方便你按資源限制加載模型的一部分內(nèi)存映射則允許操作系統(tǒng)按需讀取磁盤上的權(quán)重而不是一次性全載入內(nèi)存這對小內(nèi)存設(shè)備很友好。Ollama、llama.cpp、LM Studio 這些主流工具都原生支持 GGUF所以現(xiàn)在做端側(cè)部署很少有人再手動轉(zhuǎn) PyTorch 權(quán)重了。自己動手轉(zhuǎn)換其實(shí)也方便。先下載 HuggingFace 上的原版權(quán)重再用 llama.cpp 倉庫里的convert_hf_to_gguf.py腳本轉(zhuǎn)成 FP16 GGUF然后用量化工具壓成目標(biāo)等級。不過如果你不是要魔改模型直接用 Ollama 模型庫或 HF 上現(xiàn)成的 GGUF 文件會更省事沒必要重復(fù)造輪子。3.3 量化精度選擇Q4_K_M、Q5_K_M、Q8_0量化等級不是越高越好要跟硬件內(nèi)存和場景穩(wěn)定性需求匹配。我用得最多的幾個(gè)等級以 7B 模型為例整理如下量化等級近似模型大小質(zhì)量表現(xiàn)適用場景Q4_K_M4.7GB均衡工具調(diào)用基本可用大多數(shù)端側(cè) Agent 首選Q5_K_M5.6GB更穩(wěn)指令遵循更好內(nèi)存有余量時(shí)優(yōu)先Q8_07.2GB接近無損開發(fā)調(diào)試、效果對比IQ4_XS4.0GB壓縮激進(jìn)質(zhì)量下降明顯內(nèi)存實(shí)在不夠時(shí)的兜底絕大多數(shù)端側(cè)項(xiàng)目我會從 Q4_K_M 起步。它的體積控制合理DPO 過的模型在 Q4 下工具調(diào)用能力通常不會斷崖式下降。如果你發(fā)現(xiàn)模型在復(fù)雜指令或 function calling 上頻繁出錯(cuò)再往上升一檔到 Q5_K_M先不要懷疑代碼很多“玄學(xué)”問題其實(shí)是量化精度引起的。3.4 Token 與 KV Cache 的基礎(chǔ)認(rèn)知部署過程中很多人對 Token 的概念含糊。Token 不是字符而是模型處理的最小文本單元可能是詞、詞根或幾個(gè)字符的組合。模型一次生成多少個(gè) Token直接對應(yīng)它的處理粒度。這也是為什么同樣一段中文不同分詞器消耗的 Token 數(shù)可以相差很大。在 Agent 場景里工具定義和系統(tǒng)提示會占用大量 Token。比如你給模型綁定了 5 個(gè)函數(shù)每個(gè)函數(shù)帶參數(shù)描述和示例光工具定義就可能吃掉幾百個(gè) Token留給真實(shí)對話的上下文余量就少了。這個(gè)“隱性成本”常被忽略等 Agent 聊到一半突然“失憶”排查半天才發(fā)現(xiàn)是上下文被工具描述塞滿了。KV Cache 則是推理過程中緩存歷史計(jì)算結(jié)果的顯存區(qū)域長度隨上下文窗口線性增長。你設(shè)num_ctx8192KV Cache 占用就比 2048 大四倍。在端側(cè)設(shè)備上上下文窗口不是想開多大就多大內(nèi)存換不來就卡死給你看。所以部署時(shí)先定一個(gè)較小的上下文再按實(shí)際需要逐步調(diào)大比較穩(wěn)妥。4. Ollama 本地部署實(shí)操4.1 安裝、拉取模型、基本參數(shù)Ollama 是目前端側(cè)部署最省心的工具它把模型下載、格式轉(zhuǎn)換、運(yùn)行時(shí)加載、API 服務(wù)全部封裝好了新手不用懂底層細(xì)節(jié)就能把模型跑起來。安裝命令很簡單Linux 下一條腳本macOS 用 HomebrewWindows 有安裝包沒什么好糾結(jié)的。curl -fsSL https://ollama.com/install.sh | sh裝完以后拉模型就像拉 Docker 鏡像一樣方便。我用 Qwen2.5 系列的 7B 量化版本做主力原因是它中文支持好官方倉庫直接就有 Q4_K_M 分片不用自己折騰轉(zhuǎn)換。ollama pull qwen2.5:7b-q4_K_M ollama run qwen2.5:7b-q4_K_M第一次運(yùn)行會自動加載模型之后再把模型常駐在內(nèi)存里推理速度會快很多。這里有個(gè)小經(jīng)驗(yàn)剛裝完 Ollama 先不要急著調(diào)參數(shù)用默認(rèn)配置跑一遍簡單的對話把基線數(shù)據(jù)記下來后面優(yōu)化才有參照。4.2 上下文與運(yùn)行參數(shù)調(diào)優(yōu)默認(rèn)配置下 Ollama 的上下文窗口經(jīng)常不夠用Agent 場景里尤其明顯。你可以通過環(huán)境變量設(shè)置默認(rèn)上下文長度也可以在運(yùn)行時(shí)通過/set parameter臨時(shí)調(diào)整。我的習(xí)慣是先在啟動服務(wù)時(shí)設(shè)好一個(gè)基礎(chǔ)值然后在代碼層按任務(wù)類型覆蓋。OLLAMA_CONTEXT_LENGTH4096 OLLAMA_NUM_PARALLEL1 ollama serve模型溫度默認(rèn)是 0.8這個(gè)值對創(chuàng)意寫作沒問題但對 Agent 來說太高了。工具調(diào)用和 JSON 輸出要求確定性溫度太高模型很容易“發(fā)揮想象力”生成出格式亂七八糟的字段。我在 Agent 場景基本會把溫度壓到 0 或 0.1同時(shí)把top_p相應(yīng)調(diào)低讓模型盡量走更穩(wěn)的生成路徑。還有一個(gè)容易踩坑的點(diǎn)CPU/GPU 混合加載。Ollama 檢測到顯存或內(nèi)存不足時(shí)會自動把一部分層放到 CPU 跑這會導(dǎo)致性能驟降。在 Jetson 這類統(tǒng)一內(nèi)存的設(shè)備上沒有這個(gè)問題但在 NUC 或一些老平臺上最好手動指定層數(shù)避免全部往 CPU 上塞。4.3 開放 OpenAI 兼容接口Ollama 從較新版本開始自帶 OpenAI 兼容端點(diǎn)/v1/chat/completions可以直接復(fù)用現(xiàn)有 Agent 框架不用改代碼就能把模型接進(jìn)去。這個(gè)設(shè)計(jì)非常聰明等于把所有依賴 OpenAI SDK 的上層應(yīng)用全部平移過來。from openai import OpenAI client OpenAI( base_urlhttp://127.0.0.1:11434/v1, api_keyollama, ) chat client.chat.completions.create( modelqwen2.5:7b-q4_K_M, messages[ {role: system, content: 你是一個(gè)本地智能體助手只輸出 JSON 格式結(jié)果。}, {role: user, content: 幫我查一下今天有哪些定時(shí)任務(wù)需要執(zhí)行。}, ], temperature0, ) print(chat.choices[0].message.content)如果你的 Ollama 版本沒有/v1端點(diǎn)及時(shí)升級版本基本就能解決。實(shí)在跑在老版本上也可以用 FastAPI 包一層把/api/chat的響應(yīng)映射成 OpenAI 的字段結(jié)構(gòu)。但說實(shí)話直接用新版 Ollama 是性價(jià)比最高的路。局域網(wǎng)內(nèi)需要給其他設(shè)備提供模型服務(wù)時(shí)設(shè)置OLLAMA_HOST0.0.0.0:11434即可這樣同一網(wǎng)絡(luò)下其他設(shè)備能通過 HTTP 調(diào)用。不過要注意盡量不要把端口直接暴露到不可信網(wǎng)絡(luò)環(huán)境畢竟 Ollama 本身沒有完整的訪問認(rèn)證體系。5. 端側(cè) Agent 的接入與編排5.1 從 LLM 到 Agent工具調(diào)用的坑單純把模型跑起來只是第一步真正讓它成為 Agent還得把工具調(diào)用鏈路打通。LLM 本質(zhì)上是一個(gè)“下一詞預(yù)測”引擎它并不知道什么叫“調(diào)用函數(shù)”。為了讓模型輸出結(jié)構(gòu)化的指令你得用提示詞和微調(diào)技巧引導(dǎo)它讓它把工具調(diào)用以固定格式輸出出來。云端大模型經(jīng)過大規(guī)模 function calling 微調(diào)輸出質(zhì)量很高但端側(cè)小模型沒那么聽話。我在實(shí)際測試?yán)镉龅阶疃嗟膯栴}有三個(gè)一是模型返回的 JSON 格式不完整少一個(gè)花括號或逗號二是參數(shù)名跟工具定義對不上模型把location寫成loc三是模型干脆自己編造了一個(gè)不存在的工具名。這些在云端可能很少見在端側(cè)卻是家常便飯。應(yīng)對思路是“約束在前校驗(yàn)在后”。先把工具定義寫得盡量簡單參數(shù)越少越好同時(shí)在系統(tǒng)提示詞里給一個(gè)完整示例告訴模型層層嵌套的 JSON 結(jié)構(gòu)長什么樣。然后應(yīng)用層統(tǒng)一做 JSON Schema 校驗(yàn)不合法就觸發(fā)重試而不是把錯(cuò)誤結(jié)果直接傳下去執(zhí)行。5.2 用輕量框架把 LLM 變成 Agent如果你還在自己寫 prompt 拼接邏輯我建議直接用 LangChain 或 LlamaIndex 這類框架把模型包裝成 Agent。它們已經(jīng)實(shí)現(xiàn)了工具綁定、循環(huán)執(zhí)行、記憶管理等通用邏輯你可以把注意力放在業(yè)務(wù)編排上而不是重復(fù)造輪子。因?yàn)?Ollama 有 OpenAI 兼容接口接入框架只需要改 base_url 和 api_keyfrom langchain_openai import ChatOpenAI llm ChatOpenAI( modelqwen2.5:7b-q4_K_M, base_urlhttp://127.0.0.1:11434/v1, api_keyollama, temperature0, )接下來定義兩個(gè)工具函數(shù)比如查詢天氣和查數(shù)據(jù)庫然后用bind_tools把它綁定到模型上。端側(cè)模型綁定多個(gè)工具時(shí)如果頻繁出現(xiàn)參數(shù)錯(cuò)誤我會臨時(shí)減少工具數(shù)量把 Agent 拆分成多個(gè)子任務(wù)每個(gè)子任務(wù)只綁定 1-2 個(gè)工具。這個(gè)策略聽上去很簡單卻比在同一個(gè)上下文里硬塞 10 個(gè)工具穩(wěn)定得多。另一個(gè)建議是別迷信框架的 ReAct 循環(huán)。端側(cè)模型有時(shí)候會在“思考-行動-觀察”之間反復(fù)循環(huán)出不結(jié)果我一般會給整個(gè) Agent 加一個(gè)最大步數(shù)限制超過就停止并返回給用戶一個(gè)明確的“需要更多信息”提示。5.3 并發(fā)與吞吐端側(cè)模型扛得住嗎有不少人問端側(cè) Agent 能不能扛并發(fā)這個(gè)問題的答案很現(xiàn)實(shí)不能跟云端比但也不是完全不能并發(fā)。Ollama 支持通過OLLAMA_NUM_PARALLEL設(shè)置并行請求數(shù)默認(rèn)策略是串行或非常有限的并行。把并發(fā)調(diào)大之后每個(gè)請求都要維護(hù)獨(dú)立的上下文緩存合起來占用內(nèi)存成倍增長板子內(nèi)存不夠時(shí)只會適得其反。Agent 場景的“并發(fā)”和普通 Web 服務(wù)也不太一樣。一個(gè) Agent 任務(wù)往往包含多輪工具調(diào)用每一輪都要重新進(jìn)入模型推理所以單個(gè)用戶的前端請求可能就會連續(xù)產(chǎn)生 5-10 次推理。如果同時(shí)又來了幾個(gè)用戶后端就很容易被打滿。我的做法是在應(yīng)用層再加一個(gè)任務(wù)隊(duì)列把請求排隊(duì)后逐個(gè)交給模型處理保證每個(gè)請求拿到完整的上下文而不是讓模型被多個(gè)請求的碎片塞爆。OLLAMA_NUM_PARALLEL2 ollama serve在 Jetson Orin NX 上我測試過并發(fā)從 1 調(diào)到 2單請求延遲會小幅上升但總吞吐量能提高 40% 左右調(diào)到 4 以后反而可能因?yàn)閮?nèi)存不足觸發(fā)模型卸載延遲劇烈抖動。所以并發(fā)不是越大越好要按實(shí)際內(nèi)存和延遲數(shù)據(jù)來定。6. 常見問題排查與避坑清單6.1 內(nèi)存爆掉與加載失敗端側(cè)部署最常見的失敗就是模型加載不進(jìn)去?,F(xiàn)象是ollama run后長時(shí)間卡住或者日志里出現(xiàn) “no space”“cannot allocate memory” 之類的錯(cuò)誤嚴(yán)重時(shí)整個(gè)系統(tǒng)卡死。這個(gè)問題的直接原因通常是內(nèi)存不足。排查順序建議這樣先看設(shè)備真實(shí)可用內(nèi)存free -h在 Linux 下直接能看再看模型文件大小確認(rèn)是不是目標(biāo)量化等級比設(shè)備內(nèi)存還大最后看 Ollama 日志確認(rèn)模型是加載到了 GPU 還是 CPU以及當(dāng)前有沒有多個(gè)模型同時(shí)常駐。Jetson 設(shè)備上還可以用tegrastats實(shí)時(shí)查看顯存和頻率。解決思路也分幾步換成更激進(jìn)的量化等級、降低上下文窗口、同時(shí)只保持一個(gè)模型常駐。如果設(shè)備有 Swap可以把 Swap 打開作為應(yīng)急兜底但注意不要完全依賴 Swap因?yàn)轭l繁換頁會讓推理速度跌到不可用。6.2 速度慢、卡頓、重復(fù)輸出模型跑起來了但每秒生成一兩個(gè) Token這種體驗(yàn)基本沒法做 Agent。排查第一步是確認(rèn)模型到底跑在什么硬件上。很多設(shè)備標(biāo)稱有 NPU但 Ollama 實(shí)際可能沒用到退到了 CPU 推理。你可以通過日志或任務(wù)管理器確認(rèn)如果發(fā)現(xiàn)模型加載在 CPU就要考慮更換支持硬件加速的運(yùn)行時(shí)或者接受現(xiàn)實(shí)換更小模型。另一個(gè)常見問題是輸出“復(fù)讀機(jī)”。Agent 模型在生成長文本時(shí)容易出現(xiàn)重復(fù)循環(huán)尤其當(dāng)上下文很長、量化損失又大的時(shí)候。解決方法是把repeat_penalty從默認(rèn)值往上調(diào)我一般從 1.1 起步最高試到 1.3。溫度也需要往低調(diào)溫度越高隨機(jī)性越強(qiáng)越容易出現(xiàn)無意義的循環(huán)??D還有一個(gè)隱藏因素是 prompt 太長特別是把大段系統(tǒng)提示詞和工具描述全部塞進(jìn)去后每次推理都要重新處理這些固定前綴。Ollama 有 prompt caching 機(jī)制重復(fù)相同的系統(tǒng)前綴能顯著提速所以建議大家把系統(tǒng)提示詞固定下來不要每次改動。6.3 工具調(diào)用格式錯(cuò)亂怎么辦我之前提過端側(cè)模型工具調(diào)用不穩(wěn)定是常態(tài)但真正崩潰時(shí)排查路徑還是很有規(guī)律的。第一步先檢查系統(tǒng)提示詞里是否有明確的輸出格式示例而不是只在工具描述里寫 JSON Schema。很多模型對抽象 Schema 的理解能力有限但看到一兩行具體示例就會好很多。第二步是明確區(qū)分錯(cuò)誤類型。如果模型輸出能解析成 JSON 但字段錯(cuò)誤那就是語義問題要寫映射代碼做容錯(cuò)如果連 JSON 都解析不了那就是生成質(zhì)量問題準(zhǔn)備一個(gè)重試循環(huán)最多重試兩三次仍失敗就轉(zhuǎn)人工兜底。以下這個(gè)片段我經(jīng)常用來做后處理import re import json def extract_json(text: str): # 去掉模型可能加的多余說明文字 text re.sub(r^[^{]*, , text) try: return json.loads(text) except json.JSONDecodeError: # 嘗試截取第一個(gè)完整的 JSON 對象 start text.find({) end text.rfind(}) if start -1 or end -1: raise ValueError(no json found) return json.loads(text[start:end1])這個(gè)方法不算優(yōu)雅但在端側(cè)模型身上確實(shí)能救回不少本來要失敗的調(diào)用。注意它只能兜底格式問題改不了參數(shù)值錯(cuò)誤業(yè)務(wù)上還是需要有校驗(yàn)邏輯。6.4 避坑清單結(jié)合我自己的實(shí)操經(jīng)驗(yàn)端側(cè) LLM 部署有幾個(gè)很容易踩的坑整理出來給你避雷不要一上來就開超長上下文先把num_ctx定在一個(gè)保守值比如 2048跑通全流程后再逐步放大。不要在沒搞清楚內(nèi)存余量的情況下調(diào)大OLLAMA_NUM_PARALLEL并發(fā)帶來的內(nèi)存膨脹經(jīng)常直接觸發(fā) OOM。不要只看模型排行榜選模型端側(cè)真正重要的是量化體積和工具調(diào)用穩(wěn)定性這兩項(xiàng)才是瓶頸。不要同時(shí)常駐多個(gè)模型Ollama 默認(rèn)會保留最近用過的模型這在小內(nèi)存設(shè)備上非常致命用完了及時(shí)卸載。不要假設(shè)量化好的模型行為跟原版一致工具調(diào)用、格式化輸出這些能力必須在量化版本上重新測。不要讓 Agent 循環(huán)沒有步數(shù)上限一旦模型陷入“思考-行動-觀察”死循環(huán)整個(gè)任務(wù)就會卡死。7. 最后分享一些個(gè)人實(shí)操體會跑了不少板子之后我的體會是端側(cè) Agent 的價(jià)值不在于“參數(shù)比云上大模型還多”而在于它把推理延遲、隱私邊界和數(shù)據(jù)所有權(quán)都拿回到本地。實(shí)際做項(xiàng)目時(shí)我會先用一臺 16GB 內(nèi)存的開發(fā)板把 Agent 全流程跑通模型選擇永遠(yuǎn)從“現(xiàn)有硬件的量化體積倒推”而不是先挑一個(gè)參數(shù)最大的模型再找硬件。踩過幾次坑之后我已經(jīng)習(xí)慣先把num_ctx固定在 2048并發(fā)設(shè)為 1用腳本模擬 20 輪工具調(diào)用確認(rèn)沒有格式錯(cuò)亂后再談優(yōu)化。端側(cè)部署這條路沒有捷徑但把基礎(chǔ)打扎實(shí)了后面接 Agent 會順暢很多。希望這篇文章能幫你少走幾步彎路。