vLLM 是什麼?
vLLM 是目前最快的開源 LLM 推理引擎之一,核心創新是 PagedAttention,類似作業系統的虛擬記憶體管理,大幅減少 KV Cache 浪費。
- 吞吐量:比 HuggingFace Transformers 快 24 倍
- 並發:支援高並發請求
- OpenAI 兼容 API:無縫遷移
安裝
pip install vllm
部署模型
# 啟動 OpenAI 兼容 Server
vllm serve Qwen/Qwen2.5-7B-Instruct --port 8000
# 量化部署(減少記憶體)
vllm serve Qwen/Qwen2.5-7B-Instruct --quantization awq --port 8000
# 指定 GPU 記憶體
vllm serve Qwen/Qwen2.5-7B-Instruct --gpu-memory-utilization 0.9
在 Claude Code 中使用
{
"apiKey": "not-needed",
"baseURL": "http://localhost:8000/v1",
"model": "Qwen/Qwen2.5-7B-Instruct"
}
效能調優
| 參數 | 建議值 | 說明 |
|---|---|---|
--max-model-len | 8192 | 最大上下文長度 |
--gpu-memory-utilization | 0.9 | GPU 記憶體利用率 |
--tensor-parallel-size | GPU 數量 | 多 GPU 張量並行 |
PagedAttention 與 KV Cache 的取捨
理解 KV Cache 的記憶體行為,是調優的前提。生成過程中,每個請求都要為已處理的 token 保留鍵值快取,長上下文與高並發會把這塊記憶體迅速吃光。早期做法為每個請求預留一整段連續空間,造成大量內部碎片;PagedAttention 把快取切成固定大小的區塊,按需分配,用多少給多少,因此能用更少記憶體容納更多並發請求。
區塊大小(block size):區塊越小,碎片越少但管理開銷越高;區塊越大,管理簡單但尾端浪費增加。多數情況用預設值即可,除非在特定工作負載下觀察到明顯的記憶體浪費。
前綴快取(prefix caching):若大量請求共用相同的開頭(例如同一段系統提示或同一份長文件),開啟前綴快取可以避免重複計算,直接複用已算好的快取區塊,對吞吐有明顯幫助。代價是需要額外管理快取的生命週期與淘汰。
分塊預填充(chunked prefill):把長提示的預填充拆成多段執行,讓生成與預填充交錯,能降低長提示對其他請求的阻塞,改善整體延遲分佈。但拆得越細,單次計算效率略降,需要在吞吐與延遲之間取捨。
量化:AWQ 或 GPTQ 等量化能顯著降低權重佔用的記憶體,換取部分精度。原則是先確認輸出品質可接受,再談省下的記憶體能換多少並發。
部署參數的實務調整
| 參數 | 調整方向 | 取捨 |
|---|---|---|
--max-model-len | 依實際需求設定,不要一次開到最大 | 開太大會預留過多 KV Cache 空間 |
--gpu-memory-utilization | 依顯卡與同機其他程序調整 | 太高有機會被其他程序搶佔而失敗 |
--tensor-parallel-size | 設為實際使用的 GPU 數量 | 設錯無法啟動或效率下降 |
--max-num-seqs | 依延遲目標調整並發上限 | 越高吞吐越好但單請求延遲上升 |
--dtype | 依硬體支援選擇 | 精度與速度的平衡 |
| 量化選項 | 記憶體不足時考慮 | 精度可能下降 |
實務流程是先把模型跑起來確認可服務,再逐步加壓找出穩定上限。--gpu-memory-utilization 不是越高越好:同一台機器上若有其他程序(例如另一個服務或監控工具)需要顯存,留一點餘量能避免啟動或執行中途失敗。多 GPU 部署時,--tensor-parallel-size 必須與實際可見的 GPU 數量一致,並確認機器內 GPU 之間的連線頻寬足夠,否則張量並行的收益會被打折。
效能基準測試方法
沒有量測就沒有調優。以下做法能讓比較結果可信。
- 固定輸入長度與輸出長度,避免每次測試條件不同。
- 先做暖機,等模型載入與快取穩定後再開始計時。
- 做併發掃描:從單請求逐步提高同時請求數,觀察吞吐與延遲如何變化。
- 分別量測首 token 延遲(等待時間)與每 token 生成時間,兩者對體驗的影響不同。
- 記錄吞吐(每秒處理的 token 數)與延遲的分位數,不要只看平均值,平均值會掩蓋長尾。
- 每次只改一個參數,並保留原始數據以便回溯。
- 注意散熱與降頻,長時間連測會讓後段數據偏低。
建議把測試腳本化並固定環境,這樣換模型、換量化或換參數時可以快速重跑並對照。若同時看吞吐與延遲,通常會看到一條取捨曲線:併發越高吞吐越高,但每個請求的等待越久,最終要依業務的可接受延遲來決定工作點。
常見錯誤與檢查清單
常見錯誤
- 把
--max-model-len直接開到模型上限,導致可服務的並發數大幅下降。 --gpu-memory-utilization設得過高,與同機其他程序搶佔顯存而啟動失敗。--tensor-parallel-size與實際 GPU 數量不符,服務無法啟動。- 只看吞吐數字,忽略延遲分佈,實際使用者體驗很差。
- 在沒有暖機的情況下比較兩組設定,結論不可靠。
- 開了量化卻沒有重新檢查輸出品質。
- 把
apiKey當成必要欄位,誤以為本地服務也需要驗證才能連線。 - 服務綁定在公開介面卻沒有任何存取控制。
檢查清單
- 已確認模型可正常載入並回應請求。
- 已依實際需求設定
--max-model-len。 - 已為其他程序保留適度的顯存餘量。
- 已確認
--tensor-parallel-size與 GPU 數量一致。 - 已決定是否需要開啟前綴快取。
- 已量測首 token 延遲與每 token 生成時間。
- 已記錄吞吐與延遲分位數,並做過併發掃描。
- 已確認量化後的輸出品質可接受。
- 已確認服務的網路綁定與存取控制符合預期。