批次處理與多使用者
一次一個請求是每個桌面連線的起點——而它浪費 GPU。服務部署的全部遊戲就是批次:讓一次穿過權重的運算同時服務多個請求。這一頁涵蓋它為什麼有效、連續批次與分頁注意力到底是什麼、什麼時候需要真正的服務引擎、以及怎麼估算容量。
為什麼串行服務浪費 GPU
回想速度公式:每個解碼的 token 都要把本質上全部活躍權重讀一次(速度)。只服務一個串流時,GPU 為一個使用者的一個 token 做整趟讀取。現在把八個串流打包進同一次前向計算:權重讀一次、給八個序列用——額外的算術幾乎免費,因為解碼受頻寬而非算力限制。每串流速度幾乎不掉,總吞吐量近乎線性攀升,直到頻寬或 KV 記憶體飽和。這一個事實就是本機服務的全部經濟學。
靜態 vs 連續批次
天真的版本——靜態批次——把一起到達的請求分組,跑到每個成員都結束。它能動,但很差:
| 靜態批次 | 連續批次 | |
|---|---|---|
| 批次何時成形 | 一次,群組到齊時 | 每個解碼步驟重新評估 |
| 中途加入 | 否——等下一批 | 是,請求一到就填入插槽 |
| 長批次中的短請求 | 卡到最長的結束 | 立即結束並釋放插槽 |
| 尾端延遲 | 差(隊頭阻塞) | 好 |
連續(迭代級)批次——vLLM 與 SGLang 的預設——就是那些引擎在真實流量下撐得住、而天真伺服器垮掉的原因。
分頁注意力:修好 KV 碎片化
每個活躍請求都需要 KV 快取記憶體(見 KV 快取)。舊做法預先保留每個請求的最大上下文——一段用 2k token 的對話可能佔著一個保留的 32k 區塊,鎖死、別人不能用。KV 池大部分在納涼。分頁注意力把 KV 存進按需配置的固定大小區塊,就像 OS 對記憶體分頁:浪費從多數(vLLM 作者在論文中回報 60–80%)掉到幾個百分點,能塞的並行序列多好幾倍,吞吐量隨之而來。同樣的想法,如今是服務引擎的標配。
對你的成本:使用者端什麼都沒有——它是配置器的改變;你只會看到同一張 GPU 上更高的並行容量。
何時需要真正的服務引擎
| 工作負載 | 引擎 |
|---|---|
| 你加家人、幾段串行對話 | Ollama / LM Studio——已經夠用 |
| 幾個開發者同時摸索 | 開平行插槽的 llama-server,或 Ollama 平行環境變數 |
| 產品流量、團隊聊天、真實使用者 | vLLM 或 SGLang |
| 共享長系統提示詞的智慧代理艦隊 | SGLang(前綴快取)或 vLLM |
本論壇的 遊戲專區 是最後一列的標準範例:西洋棋 與 韓國將棋 對局跑多個智慧代理,每個大約每秒請求一步——提示詞小、串流多、系統提示詞共享。那正是需要帶批次的服務引擎的工作負載,不是迴圈裡的 ollama run(見 智慧代理)。
吞吐量 vs 延遲
每個旋鈕都在兩者之間交換:更大的批次提高總 tok/s、略降每串流速度;排隊則讓負載下的 TTFT 上升。單人程式助理要把並行壓在 1–2,讓人類的串流永不排隊。三十人的聊天服務要把批次塞滿。調校前先決定你是哪一種(TTFT 與解碼是不同的測量,見 端點服務)。
最接近免費午餐的是前綴快取(SGLang):重複的長提示詞變成近乎零的預填,而那正是多數智慧代理工作負載。
實用旋鈕
# llama.cpp: parallel decode slots (context is split across slots)
llama-server -m model.gguf -c 32768 -np 4
# Ollama: parallel requests per model (restart service after setting)
export OLLAMA_NUM_PARALLEL=4
# vLLM: the two that matter
vllm serve model --max-num-seqs 32 --gpu-memory-utilization 0.90
排隊發生在這一切的上游:每個插槽都忙時,新請求就等。看佇列深度與 TTFT,不是憑感覺。
上游也要設限:帶連線上限的反向代理會快速而誠實地失敗;深佇列則緩慢而神秘地失敗。
粗略的容量規劃
權重之外,每個請求的成本是 KV 快取,逐 token、涵蓋整個上下文:
KV bytes/token ≈ 2 × layers × kv_heads × head_dim × bytes_per_value
實例,典型 8B 稠密模型(32 層、8 個 KV 頭、頭維度 128、fp16 值):
2 × 32 × 8 × 128 × 2 B ≈ 每 token 131 KB → 2k token 的對話 ≈ 256 MiB 的 KV → 十段這樣的對話 ≈ 在約 5 GB 權重之外再加 2.5 GB。
(那個 2 是 K 與 V;見 KV 快取)。因此長上下文智慧代理每個請求的成本遠高於聊天。粗略舒適表,重重打折扣——聊天長度的上下文、僅供數量級:
| GPU | 模型 | 大約可同時應付的輕量對話 |
|---|---|---|
| 8 GB | 7–8B Q4 | 1–3 |
| 24 GB | 8B Q4 | ~10–30 |
| 24 GB | 32B Q4 | ~3–8 |
| 48 GB | 70B Q4 | ~5–15 |
用你真實的提示詞量:上下文長度對這些數字的影響比任何變數都大。
飽和的訊號
- TTFT 隨時間從毫秒爬到秒。
- 佇列深度持續高於零;請求在第一個 token 前等待。
- 批次塞滿時每串流 tok/s 下垂。
- vLLM 日誌出現 preemption 或 KV 重算——是記憶體壓力,不是模型慢。
任何一項出現:限制上下文、量化 KV 快取、或加 GPU——按這個便宜順序——在使用者大聲抱怨之前。
把一整天的 TTFT 與佇列深度畫成圖——穩定攀升代表容量不足;鋸齒狀代表可用佇列吸收的爆發。
租 vs 買,速寫
截至目前,租用的 24GB 級 GPU 約每小時 $0.50–2,二手 24GB 卡數百美元——損益兩平大約在 300–1,000 小時的實際生成。本機贏在隱私、延遲與無速率限制(框架見 什麼是 LLM);租用贏在爆發性需求與沒有消費卡裝得下的 80GB 級模型(什麼裝在哪見 VRAM 用量計算)。多數人高估自己的時數——決定前先量測真實的一週。