跳到主要內容

【2026 最新】vLLM Preload 教學:權重快取怎麼驗?冷啟動、暖重啟與日誌五步檢查

最後更新: ·
vLLM Preload 教學 教學首圖

你重啟自架的 AI 服務,看到它又能回答,便以為加速設定成功了。vLLM Preload 教學要解決的正是這個盲點:引擎可能已回退讀磁碟,回答照常出現,卻沒用到預載的權重。

這篇寫給剛開始自架推論、願意複製指令的新手。先用白話分清三種快取,再在單 GPU 測試機建立磁碟基準、暖重啟與失敗對照;最後留下能查回日誌的驗收紀錄。實作需要已有 Linux、合適 NVIDIA GPU、驅動與 Python 環境,單純使用聊天網站的讀者可先讀概念。

截至 2026 年 10 月 10 日,本文固定使用官方 v0.31.0 發行版的介面。本次環境是 Apple Silicon Mac,沒有適用這條 CUDA 路線的 GPU;下文提供依官方程式碼與測試設計的驗收流程,沒有填入 AlphaLab 的啟動秒數或效能跑分。

先說結論:vLLM Preload 教學先驗哪四件事?

Preload=讓 daemon 留住 GPU 權重,讓新引擎重新接上。Daemon 是背景常駐程序,像一直守著食材的倉管;推論引擎是換班的廚師。廚師換人時,不必把同一批食材再搬一遍。

  • 時間:從啟動引擎,到健康檢查成功,究竟等多久。
  • 日誌:是否出現權重映射成功,是否又回退讀磁碟。
  • 記憶體:daemon 留下哪些占用,新引擎又新增哪些占用。
  • 回答:固定同一題核對結果,再重啟一次,確認流程仍成立。

最有辨識力的測試,是在暖啟動時把 fallback 關掉。Fallback 是「原路不通就改走備用路線」;關閉後,錯配不會被讀磁碟掩蓋。這個策略也出現在 官方冷啟動與暖重啟測試:測試將暖啟動的回退停用,再把輸出和一般載入基準比較。它是官方測試設計,不是本文代跑的結果。

先分清三種快取:權重、KV、Prefix

權重是模型學到的參數,像廚師的整本食譜。KV Cache 是生成文字時保存的注意力中間結果,像這次訂單的工作筆記。Prefix Cache 則讓相同的提示前綴重用先前的計算。快取(Cache)只是「保留可重用的東西」的總稱,必須追問保留的是什麼。

官方 Automatic Prefix Caching 說明把收益放在重複前綴的 prefill 計算。Preload 處理的是權重載入路徑,兩者解決不同等待。想比較請求快取,可接著讀 Agent Prefix Cache 驗收;本篇的終點是跨引擎生命週期的權重命中。

vLLM Preload 教學:權重、KV Cache 與 Prefix Cache 的分工
Preload 留住權重;KV 與 Prefix 的驗收,則要追請求計算。三者不應共用一個「有快取」結論。

① 先點名環境:vLLM Preload 教學的最小起跑線

怕一開始就被多張 GPU 和量化設定拖住?先用一張卡、一個小模型、同一份檔案。Preload 的 平台檢查程式明確限制 CUDA/ROCm;平台不符合時會直接報錯。下列指令專走 NVIDIA CUDA,AMD 安裝需另讀 ROCm 分頁。

在獨立虛擬環境使用 官方 GPU 安裝方式,把套件固定為 uv pip install vllm==0.31.0 --torch-backend=auto。這是給已備妥 uv 與 GPU 驅動的測試環境;不要混入另一套 PyTorch/CUDA 環境。先執行以下三個命令,保存輸出。

nvidia-smi
python -c 'import vllm; print(vllm.__version__)'
vllm preload --help

模型選 Qwen3-0.6B 官方模型,降低第一輪搬運負擔。以已安裝的 Hugging Face CLI下載到獨立資料夾;先在模型頁記下選定的完整 commit,將下方 MODEL_COMMIT 換成該值。下載完成後,所有跑次共用同一路徑,不再更新資料夾。

hf download Qwen/Qwen3-0.6B --revision MODEL_COMMIT --local-dir ./qwen3-0.6b

記錄 GPU 型號、驅動、vLLM 版本、模型 commit、dtype 與 TP/DP 配置。TP(張量平行)是把模型切給多張卡;DP(資料平行)是用多份引擎接不同請求。這輪兩者都維持一份。若還不清楚引擎與模型的關係,先讀 LLM 推論引擎的分工。

② 建磁碟載入基準:先量「整間廚房開門」

痛點是只比較一行權重載入秒數,卻忘了服務還要初始化。先保存一般載入的完整就緒時間。確認這張卡沒有本練習的 daemon 或引擎,且 8000 埠沒有其他服務。將下面的觀測程式存成 observe.py,用它啟動每一輪。

import json, os, signal, subprocess, sys, time, urllib.request
from datetime import datetime, timezone
label, command = sys.argv[1], sys.argv[2:]
if not command:
    raise SystemExit("Provide a server command")
started = datetime.now(timezone.utc).isoformat()
with open(label + ".log", "w") as log:
    t0 = time.monotonic()
    proc = subprocess.Popen(command, stdout=log, stderr=subprocess.STDOUT,
                            start_new_session=True)
    try:
        ready = False
        while proc.poll() is None and time.monotonic() - t0 < 600:
            try:
                with urllib.request.urlopen("http://127.0.0.1:8000/health",
                                            timeout=2) as response:
                    ready = response.status == 200
            except OSError:
                pass
            if ready:
                break
            time.sleep(1)
        receipt = {"label": label, "started_utc": started, "ready": ready,
                   "elapsed_s": round(time.monotonic() - t0, 3), "pid": proc.pid,
                   "command": command}
        with open(label + ".json", "w") as out:
            json.dump(receipt, out, ensure_ascii=False, indent=2)
        print(json.dumps(receipt, ensure_ascii=False), flush=True)
        if ready:
            proc.wait()
    finally:
        if proc.poll() is None:
            os.killpg(proc.pid, signal.SIGINT)
            try:
                proc.wait(timeout=30)
            except subprocess.TimeoutExpired:
                os.killpg(proc.pid, signal.SIGKILL)
                proc.wait()

觀測程式每秒探一次 /health,600 秒是本範例的等待預算,並非 vLLM 的服務規格;到期或引擎退出會記 ready:false 並清理本次程序。若 ready:true,它留在前景等你完成回答與記憶體記錄,再按 Ctrl+C 停引擎。就緒時間包含啟動工作與探測間隔,不等於純權重載入時間。端點含義可對照 官方端點文件。

CUDA_VISIBLE_DEVICES=0 python observe.py disk vllm serve ./qwen3-0.6b \
  --dtype float16 --tensor-parallel-size 1 --host 127.0.0.1 --port 8000 \
  --served-model-name preload-lab --enforce-eager \
  --gpu-memory-utilization 0.3 --max-model-len 2048

這裡的 0.3 與 2048 是為了縮小練習的配置,並非保證所有 GPU 放得下。--enforce-eager 讓本輪採 eager 路線;保留相同設定,避免把執行模式改變算到 Preload 頭上。顯存仍不足就先停測、減少其他占用,再把新設定記為另一組實驗。

③ 啟動 daemon:倉管就緒後,廚師才接班

先完成磁碟輪並停掉引擎。在另一個終端、同一使用者與虛擬環境、同一工作資料夾,執行下列命令;保存這個終端,讓 daemon 繼續存活。等到 Weight cache daemon READY 再啟動引擎。這個訊息來自 Preload 啟動器的就緒檢查。

CUDA_VISIBLE_DEVICES=0 vllm preload --model ./qwen3-0.6b \
  --dtype float16 --tensor-parallel-size 1

Preload 自己要先把權重載入並處理好,所以不要把 --load-format ipc_cache 加到 daemon 命令。這一步的時間單獨記成「預載準備時間」;若你只啟動一次服務,準備成本也得算進整體等待。這套安排最適合評估同一模型反覆重啟的服務。

④ 暖啟動與暖重啟:關掉 fallback,驗真的命中

回到原終端,將一般載入改成 ipc_cache,加上 {"fallback":false}。IPC(程序間通訊)在這裡讓新引擎接上 daemon 持有的 GPU 配置。第一輪記 warm1;完成後只停引擎,保留 daemon,再將標籤改成 warm2 重跑同一命令。

CUDA_VISIBLE_DEVICES=0 python observe.py warm1 vllm serve ./qwen3-0.6b \
  --dtype float16 --tensor-parallel-size 1 --host 127.0.0.1 --port 8000 \
  --served-model-name preload-lab --enforce-eager \
  --gpu-memory-utilization 0.3 --max-model-len 2048 \
  --load-format ipc_cache --model-loader-extra-config '{"fallback":false}'

在第三個終端查 warm1.log,尋找 Mapped、weight cache daemon 與模式名稱;這是 IPC loader 寫出的成功日誌。另查 falling back to disk loading。不要把別的快取訊息、HTTP 200 或 daemon READY 當成引擎命中。單卡只有一個 worker,之後擴到多卡則逐 rank 對帳。

grep -E 'Mapped|weight cache|falling back' warm1.log
nvidia-smi --query-gpu=uuid,memory.used,memory.total --format=csv
curl --fail http://127.0.0.1:8000/v1/completions \
  -H 'Content-Type: application/json' \
  -d '{"model":"preload-lab","prompt":"The capital of France is","temperature":0,"max_tokens":16}'

把同一份題目送給 disk、warm1、warm2,各保存回應。這個短題驗模型能產生合理結果,不能替你的長文件、工具呼叫或商務任務驗收;之後再追加自己的任務。回答的檢查與權重命中是兩份證據,兩份都通過才保留配置。

vLLM Preload 教學:就緒時間、映射日誌、GPU 記憶體與回答四份驗收證據
比較 disk、warm1、warm2 時,固定配置、分開記預載成本;這張圖是紀錄欄位,並非量測結果。

記憶體也要在「都未啟動」「只有 daemon」「daemon 加引擎」「只停引擎」四個時點取樣。預設 zero_copy 共用權重,但 KV Cache、執行工作區等仍會占用記憶體;所以整張卡的 used 數字增加,不足以證明權重被複製。需要更完整容量模型,可讀 本機 LLM 顯存規劃。

⑤ 故障演練:把可用與命中拆成兩個結果

痛點是故障被備用路徑藏住。先停引擎,再停 daemon。在 daemon 原終端按 Ctrl+C,等它退出,再以另一個標籤 miss 跑相同命令但把 loader config 改為 {"fallback":true};應檢查是否出現回退日誌、服務能否就緒及回答。隨後以 strict-miss 和 {"fallback":false} 再跑一次,預期無 daemon 時無法通過命中驗收。記錄失敗與等待,別把它填成加速成功。

另一個受控情境是保留 daemon,讓引擎的 --dtype 改為 bfloat16;只在 GPU 已支援該 dtype、且預留記憶體足夠的測試機操作。核對錯配欄位,再恢復 float16。不支援 BF16 的卡先用缺 daemon 情境即可。

冷啟動在本文表示「沒有可用權重 daemon」,不代表已清空 OS 檔案快取。一般載入也可能讀到檔案快取,因此速度差異要配著日誌看。重複數輪、保留每輪原值,另記模型下載、daemon 準備與引擎就緒;這樣才知道反覆重啟省了哪一段。

四個常見坑:生命周期、顯存、配置與信任

  • 運作中殺 daemon:zero_copy 的權重依賴 daemon 的 GPU 配置;引擎運作期間要維持 daemon。計畫停止時先停引擎,再停 daemon。
  • copy 當成免費常駐:copy 模式會把張量複製進引擎,再請 daemon 釋放快取;不要照搬 zero_copy 的暖重啟假設,且交接時須預留複製空間。
  • 模型名稱相同就算配置相同:版本、dtype、量化與平行布局都參與匹配。v0.31.0 的 checkpoint 指紋使用 safetensors 標頭,不是整份權重內容的完整校驗;若檔案被替換,要以獨立檔案雜湊與不可變部署管理。
  • 把 socket 分享給其他帳戶:協定使用 pickle,只面向同節點、同使用者的可信程序。保持私有目錄與 owner 權限,別用 chmod 777 解決連線問題。

這些限制可在 官方 Preload 模式說明與 協定實作對照。zero_copy 與權重 offload 的 Sleep Mode 組合被文件明確禁止;這次練習不要開啟 Sleep Mode。伺服器只綁 127.0.0.1,也不要把本機驗收入口直接暴露到公網。

多 GPU 延伸:先核對修補狀態,再談部署

2026 年 10 月 6 日的 原始故障回報 #60178描述一個窄但重要的例子:Ubuntu 22.04、兩張 RTX A6000、Qwen3-0.6B、main commit 5f30fc7031,dense 模型在 DP=2 時,daemon 與引擎對 DP 欄位的指紋不同;預設回退後仍能回答。這是回報者的觀察,不是所有版本/模型的普遍結果。

截至 2026 年 10 月 10 日,相關 修補 PR #60179仍為 open、未合併。本文不把它寫成 v0.31.0 已含修補,也不教新手直接套用未合併分支。要延伸多 GPU,先核對你安裝的完整 commit 與修補納入情況,再要求每個 rank 都有映射證據;TP、DP、MoE 與跨節點各自新增驗收。

FAQ:vLLM Preload 教學的八個直接答案

1. API 能回答,就代表權重命中了嗎?

不能這樣判定。回退讀磁碟也可能回答;查映射日誌,另用 fallback=false 的暖啟動驗收。

2. Preload 能讓每個 token 都生成更快嗎?

本篇不承諾。它處理權重載入與重啟;生成吞吐要另測,不能把就緒時間當 tok/s。

3. Prefix Cache 命中,可以替代 Preload 驗收嗎?

不能。前者重用提示計算,後者重用常駐權重;要各自保留證據。

4. Mac 或 Intel XPU 能直接照這個 ipc_cache 流程嗎?

v0.31.0 這條 loader 明確只接受 CUDA/ROCm。可先學驗收欄位,再選對應平台的推論路線。

5. zero_copy 就表示引擎完全不吃新顯存嗎?

不是。共用的是權重;KV 與執行工作區仍需預算。

6. 模型路徑相同,快取就一定匹配嗎?

不一定。還要同版本、dtype、量化與布局;模型部署也要保存不可變檔案及獨立校驗。

7. 故障演練可以直接殺運作中的 daemon 嗎?

本篇採先停引擎的順序。zero_copy 引擎依賴 daemon 存活,運作中故障要另外設計服務恢復演練。

8. 多 GPU 的回報代表整個 Preload 都不能用嗎?

不能如此外推。先保留原回報的版本與 dense DP 配置,再對自己的每個 rank 驗收。

給新手的三個重點

  • 先做單卡對照:同檔、同版本、同 dtype,才能把變化連回載入路徑。
  • 速度是結果,日誌是路徑證據;暖啟動關閉 fallback,讓錯配浮上來。
  • daemon 的生命週期、占用與準備成本,都屬於服務維運的一部分。

下一步:留下第一份暖重啟紀錄

記住:倉管留住權重,廚師換班重新接上。今天先完成 disk、warm1、warm2 與缺 daemon 的對照,把就緒時間、映射日誌、GPU 記憶體和回答留在同一資料夾。四份證據對得上,再把小模型換成真正要服務的模型。更多路線可從 AlphaLab AI 專區繼續探索,或到 AlphaLab 課程建立完整的 AI 系統工作流。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週最多三封:一封 Weekly 週報與最多兩封關鍵 Alpha Signal。

我們不會 spam,隨時可退訂。已訂閱?管理主題偏好(會寄登入連結到你的信箱)