vLLM 是大型語言模型的推理與服務引擎,透過記憶體管理、快取重用與請求排程,讓同一套硬體更有效率地服務多個使用者
當模型已經能跑,真正的問題往往是多人同時進來之後,顯存不夠、請求排隊,以及輸出忽快忽慢。
「同一張 GPU 接更多請求」主要談的是服務吞吐量,不代表單一回答一定快上數倍,要看懂 vLLM,可以先把 KV Cache、PagedAttention、Prefix Caching 與 Continuous Batching 串起來,再看哪些參數適合自己的負載。
內容目錄
vLLM 在解決什麼問題?從能生成文字,到能穩定提供服務
把模型載入 GPU,再包一層 HTTP API,就能讓應用呼叫,但模型請求的輸入、輸出長度各不相同,若逐一處理,其他使用者只能排隊,即使改成批次,長短請求與記憶體配置也可能拖低利用率。
vLLM 把這些服務層問題放在同一個引擎處理,包含批次推理、排程、模型執行,以及相容 OpenAI 格式的部分 API。它不會因為換了引擎,就讓原本的模型權重具備新的知識。
如果還在選工具,可以先看站上的本地大模型推理框架比較。選型時要問的是部署情境、併發量與維運需求,不能只把不同工具放在同一個速度排名裡。
KV Cache:省下重算,代價是占用記憶體
典型自回歸 Transformer 會逐步產生 token,為了讓新的 token 利用前文,每層注意力運算都需要先前位置的 Key 與 Value 張量,這些中間結果可以保留下來,供後續步驟使用,稱為 KV Cache。
可以把它理解成已經整理好的閱讀筆記,每寫下一個字,不必從頭重做前面所有位置的 K、V 投影,但仍需要用前文狀態參與後續注意力計算。它節省重算,也會隨序列與併發請求增加而占用更多記憶體。
這也連到兩個不同階段:Prefill 先處理輸入並建立狀態,Decode 再逐步生成輸出。想更細看兩階段與等待時間的關係,可以延伸閱讀Prefill、Decode 與本地 AI 硬體的區分,其中的概念也適合用來理解伺服器負載。
上下文加倍,KV Cache 會增加多少?
對採用完整注意力、保存每個位置 K、V 的簡化配置,單一序列的理論用量可用下面的式子估算。這裡要用 KV 頭數,不能一律拿 Query 頭數代入。不同模型的 GQA、滑動視窗、壓縮狀態與其他設計,會改變實際需求。
KV Cache 位元組數 ≈ 2 × 層數 × KV 頭數 × 每頭維度 × tokens 數 × 每個元素的位元組數
以下是假設 40 層、40 個 KV 頭、每頭維度 128、FP16 每個元素 2 bytes、單一序列的算術示例。它不是指定模型或 GPU 的 benchmark,也不包含模型權重、配置器額外空間與執行暫存。GiB 以 2³⁰ bytes 計。
| 已保存的 tokens | 理論 KV Cache 用量 |
|---|---|
| 512 | 約 0.391 GiB |
| 1,024 | 約 0.781 GiB |
| 2,048 | 約 1.563 GiB |
| 4,096 | 約 3.125 GiB |

所以,顯卡裝得下模型,不代表還能接很多長對話。固定權重之外,每個請求都需要自己的執行狀態。長輸入、長輸出與多人併發,會一起壓縮剩餘空間。
PagedAttention:把 KV Cache 拆成可以管理的小區塊
如果替每個請求預留很大的連續空間,短請求可能用不完,空間也容易因配置方式而難以有效重用。PagedAttention 論文採用類似作業系統分頁的思路,把邏輯上的序列映射到可不連續的實體區塊。
例如假設每塊可放 4 個 token,7 個 token 需要兩塊,最後一塊還有一格空間。接下來需要成長時再取得新區塊,不必一開始就替整段可能的輸出保留一大塊連續空間,這只是教學示意,不是宣稱 vLLM 的預設區塊大小固定為 4。
注意力核心透過區塊對應關係讀取資料,讓分散存放的 KV 仍可參與計算,改善的是 KV Cache 的配置與共享效率,模型權重、其他暫存及最後一塊的未用空間,仍然需要記憶體預算。
Prefix Caching:相同的開頭,不必每次重新讀一遍
多個請求可能共用固定系統提示詞、同一份長文件,或同一段對話歷史。Automatic Prefix Caching 能在符合重用條件時,直接沿用相同前綴已算好的 KV。
例如反覆詢問同一份操作手冊,可以把穩定內容放前面,個別問題放後面。若每次都把時間戳、隨機內容或不同排列放在最前方,後面的共用內容也可能無法命中同一條前綴。意思相似,不等於 token 前綴完全相同。
它主要省下 Prefill 的重複計算,不會直接免除新答案的 Decode。長篇輸出占大部分時間,或請求之間沒有可重用前綴時,收益可能有限。快取也受容量、淘汰與部署方式影響,不能假設放過一次就永遠存在。
Continuous Batching:短請求完成,就讓新請求補上
假設同一批有的請求很快結束,有的還要生成很久。若整批都要等最慢的一個完成,已空出的資源就難以立刻服務新請求,Continuous Batching 讓引擎在生成迭代之間重新安排工作,已完成的請求退出,新的請求有機會加入。
這能讓 GPU 在一輪執行中處理多個序列,增加權重讀取與運算資源的利用程度,但請求數更多,也會增加每輪工作與記憶體壓力。吞吐量提高,與每個人都更快看到下一個 token,仍需要分開衡量。
Chunked Prefill:長文件分段處理,兼顧其他人的輸出
一份很長的輸入若一次占住執行時間,正在 Decode 的其他請求可能感覺輸出停頓。Chunked Prefill 把長輸入分段排入,讓 Prefill 與 Decode 工作交錯。依目前 V1 調校文件,支援的情況下會預設啟用。
--max-num-batched-tokens 控制的是單次迭代的 token 預算,不只是某一份輸入要讀幾個 token,較小的預算可能改善持續輸出的間隔,較大值有機會處理更多 Prefill 工作,但也需要更多資源,應依首個 token 等待、生成間隔與總吞吐一起調整,沒有適合所有 GPU 的固定最佳值。
先理解幾個參數,避免只把數字往上加
以下依查核當日的 Engine Arguments整理。版本、模型與後端會影響可用選項,部署時仍應查看安裝版的說明。
--gpu-memory-utilization:模型執行器使用的 GPU 記憶體比例,目前文件列出的預設是 0.92,但這不代表全部 92% 都用於 KV Cache,也不會替其他程式保證剩餘空間。--kv-cache-memory-bytes:可明確指定每張 GPU 的 KV 預算,依目前文件,設定後會覆蓋前述比例對 KV 大小的推算。--max-model-len:單請求的輸入與輸出合計上下文上限。依實際需求限制長度,不等於每個短請求都立即占滿上限。--max-num-seqs:每輪可處理的序列數上限,和同時連線數、每秒請求數不是同一個數字。--max-num-batched-tokens:每輪執行的 token 預算,須連同 Prefill、Decode 與記憶體需求觀察。
出現 Preemption,表示引擎需要先回收部分請求占用的 KV 空間,再於資源允許時恢復處理。V1 常用重新計算的方式,頻繁發生時可能拖高延遲。檢查上下文、併發限制與可用記憶體,再決定是否增加預算,不能只看到排隊就一路調高比例。
量化分兩件事:模型權重與 KV Cache
權重量化縮小的是模型參數的表示方式,KV Cache 量化縮小的是執行中的中間狀態。兩者針對不同記憶體需求,不能把一個選項的效果直接套到另一個。
從 16 位元換成 8 位元,理論上的元素資料量減半,但整體占用還包括縮放資訊、部分高精度資料與其他開銷。也不能因此直接推成服務吞吐量加倍,或所有模型的準確度都不受影響。
官方 KV 量化文件提供 FP8 路線與校準說明。實際可用格式取決於 GPU、注意力後端及模型,選 --quantization 或 --kv-cache-dtype 前,應先核對支援條件,再以自己的資料驗證品質與延遲。
一個請求,怎麼走過 vLLM?
依架構文件,可以先把 API Server、Engine Core 與 GPU Worker 視為三個分工。實際程序配置會依部署方式調整,這裡用簡化流程理解。
- API Server 接收請求,處理輸入與 token 化等前置工作。
- Engine Core 的排程器安排請求、快取空間與每輪工作。
- GPU Worker 載入模型,執行分配到的推理計算。
- 生成結果經後續處理回傳給應用,串流模式可逐步收到內容。
- 請求結束後解除相關資源持有,可重用的前綴快取則依管理策略保留或淘汰。
CPU 也參與輸入處理、排程與網路輸出。GPU 利用率不高時,不能只看顯卡規格,還要檢查 CPU、請求來源、資料處理與通訊是否已成為瓶頸。
多 GPU:能放得下,和跑得更有效率,是不同目標
官方平行部署文件提供不同分工方式。Tensor Parallelism 把層內參數與運算分到多張卡,Pipeline Parallelism 則把不同層分成階段。前者需要頻繁的跨卡通訊,後者要考慮管線利用率與延遲。
常見選項包括 --tensor-parallel-size 與 --pipeline-parallel-size。卡數增加後,互連、模型結構與批次都會影響收益,不保證線性加速。若模型本來就放得下,目標是增加服務容量,也可評估多副本的資料平行方式。
CPU offload 則讓部分權重使用系統記憶體,幫助處理容量不足,但會增加資料搬運成本。能藉此載入,不代表已符合對外服務的延遲需求,仍要量測實際負載。
從小模型服務開始,再測自己的流量
先依官方 Quickstart選擇符合平台、驅動與模型的環境。不同硬體有各自的安裝路徑,下面是在已安裝且模型受支援的環境中啟動本機服務的示例,不是特定 GPU 的效能最佳設定。
vllm serve Qwen/Qwen2.5-1.5B-Instruct \
--host 127.0.0.1 \
--port 8000 \
--max-model-len 4096 \
--max-num-seqs 16 \
--enable-prefix-caching
可先確認模型清單,再讓測試應用呼叫支援的 API。使用相容的介面格式,能減少串接修改,但不代表功能、模型行為與任何雲端服務完全相同。
curl http://127.0.0.1:8000/v1/models
確定推理服務穩定後,再接聊天介面或知識庫。像站上的 LibreChat 與模型服務分工教學,可以延伸理解前端介面、模型後端與應用設定各自負責什麼。
調校時,同時看吞吐量、等待與失敗
在相同模型、量化、輸入輸出長度與併發條件下比較,才知道改動是否有效。Production Metrics 提供排隊、快取、搶占與延遲指標,服務一般可透過 /metrics 觀察。
- TTFT:送出請求到第一個 token 的時間,可能包含排隊與輸入處理。
- ITL:持續生成時,token 與 token 之間的間隔。
- 端到端延遲:整個回答完成要多久,應連同較慢的一群請求觀察。
- KV Cache 使用率、等待請求與搶占次數:一起判斷容量壓力,不只看單一數字。
- 吞吐量與錯誤率:接更多請求時,也要確認完成品質與失敗情況。
例如快取接近滿載、排隊持續累積且搶占上升,就先檢查負載與記憶體。若 Prefill 很慢但前綴命中低,就檢查共用內容與排列。每次只改少量條件,保留基準紀錄,才看得出參數的取捨。
vLLM 的價值,在於讓模型服務更有系統地使用資源。先辨認是容量、排程、輸入處理還是通訊瓶頸,再調整對應設定,會比只追求更大的批次或更高的 GPU 使用率有效。
vLLM 常見問題
vLLM 會讓每個回答都快數倍嗎?
不保證。它能改善記憶體配置、排程與服務吞吐,但單請求延遲仍受模型、輸入輸出長度、快取、批次及硬體影響。
PagedAttention 會讓模型權重變小嗎?
不會直接縮小權重。它主要管理 KV Cache 的區塊配置與共享,權重壓縮屬於另一類量化或模型處理。
Prefix Caching 會加快新答案的生成嗎?
它主要省下相同前綴的 Prefill 計算,不直接省掉新 token 的 Decode。沒有共用前綴或快取已淘汰時,收益有限。
gpu-memory-utilization 設得越高越好嗎?
不是。它影響模型執行器的記憶體預算,還要考慮其他程式、執行暫存與工作負載。應配合排隊、搶占、延遲及失敗情況調整。
多台 vLLM 會自動共用所有 KV Cache 嗎?
不能這樣假設。跨實例或跨機器的 KV 傳輸需要支援的 Connector、相容配置與網路,例如官方有 MooncakeConnector 路線,效果仍取決於傳輸與重算成本。
跨機器快取可進一步查閱官方 MooncakeConnector 說明,