用 Python 部署本機大模型:Ollama、VRAM 預算與可用介面
本機模型是一個有記憶體預算、有延遲曲線的行程,不是黑盒。這篇實錄講清決定它能不能撐過一下午的幾件事:量化、VRAM 算術、一個 HTTP 介面、降級鏈,以及上線後該看的數字。
拉模型之前先看懂標籤
模型名後綴就是量化等級。q4_K_M 表示主權重 4 bit、敏感張量用 K 分組縮放,實際約每參數 4.5 bit。位數越低 VRAM 越省、精度略降,所以從 Q4_K_M 起步,只有自己的評測說不夠時才往上換。
params_b = 7
bits_per_weight = 4.5 # Q4_K_M,並不是整 4 bit
weights_gb = params_b * 1e9 * bits_per_weight / 8 / 1024**3
print(round(weights_gb, 2))先算權重,再談效果
KV 快取也要算進去
權重只是帳單的一半。上下文裡每個 token 都要在每一層留一份 key 和 value 向量,8k 上下文往往又是 2 到 4 GB。權重加快取裝不下時,模型會溢到 CPU,吞吐直接掉一個數量級。
def kv_cache_gb(layers, hidden, ctx, bytes_per=2):
# K 和 V 兩個張量,預設 fp16
return 2 * layers * hidden * ctx * bytes_per / 1024**3
print(round(kv_cache_gb(32, 4096, 8192), 2))上下文不是免費的
起服務,然後當普通介面呼叫
ollama serve 在 11434 埠暴露 HTTP 介面。向 /api/generate 發一個 stream 為 false 的阻塞 POST,回傳一個 JSON 物件。超時要設得比最慢的一次生成更長——預設那幾秒足夠把正常回答截斷。
import requests
payload = {
"model": "qwen2.5:7b-instruct-q4_K_M",
"prompt": "Say hi in five words.",
"stream": False,
}
resp = requests.post("http://127.0.0.1:11434/api/generate", json=payload, timeout=120)
resp.raise_for_status()
print(resp.json()["response"])一個介面,一個超時
有人在等的時候用流式
stream 為 true 時回應體是逐行 JSON:每行的 response 帶一個片段,最後一行的 done 為 true。按行解析、跳過空行、邊收邊列印,使用者不到一秒就能看到字,而不是盯著轉圈。
import json, requests
with requests.post(url, json=payload, stream=True, timeout=120) as resp:
for line in resp.iter_lines():
if not line:
continue
chunk = json.loads(line)
print(chunk.get("response", ""), end="", flush=True)
if chunk.get("done"):
breakNDJSON,一行一個片段
降級到小模型,而不是拋 500
筆記本上 VRAM 溢出、守護行程報 500 都是常態。準備一條有序的模型鏈,逐級回退,並把「最後是誰答的」記下來,日誌才能在以後解釋品質為什麼掉了。答得慢總好過拋堆疊。
MODELS = ["qwen2.5:7b-instruct-q4_K_M", "qwen2.5:3b-instruct-q4_K_M"]
def generate(prompt):
for name in MODELS:
try:
return name, call(name, prompt)
except (TimeoutError, RuntimeError):
continue
raise RuntimeError("all local models failed")可記錄的降級鏈
盯首字延遲、吞吐與失敗率
首字延遲是使用者的體感,每秒 token 數是硬體的產出。兩個都記,再按模型記失敗率;警示看中位數而不是平均數,否則一個 30 秒的離群值就能半夜叫人。
import statistics
first_token_ms = [820, 910, 780, 2400, 860]
print(round(statistics.median(first_token_ms)), max(first_token_ms))看中位數,不看平均數
你的練習清單
- 拉模型之前就寫明標籤與量化等級。
- 權重加 KV 快取裝得進 VRAM,並且留有餘量。
- 介面顯式設了超時,比最慢的一次回答更長。
- 流式輸出按行解析,能容忍空行與半行。
- 大模型 VRAM 不足時有小模型接管。
- 首字延遲、每秒 token 數與失敗率都有記錄。
常見問題
7B 模型 Q4 要多少VRAM?
權重約 4 GB,上下文快取按長度再加 1 到 4 GB。8 GB 卡比較從容;6 GB 要縮短上下文。
只有 CPU 能跑嗎?
能,每秒幾個 token。跑通宵批處理沒問題,對話體驗會很差。
用 Ollama 還是直接用 llama.cpp?
要模型管理和穩定 HTTP 介面就用 Ollama;要調採樣參數或跑特殊硬體再上 llama.cpp。
本機模型和雲上模型怎麼選?
資料不能出內網、或量大且品質夠用,選本機;要最強推理或彈性擴容,選雲上。
練一練模型監控
覆蓋漂移、延遲、小樣本評估與決策門檻值的題目。
繼續閱讀: