llm-wiki wiki · analysis 2026-10-12

本页解释一个 vLLM 实例如何从 process 创建走到 serving、暂停、释放 GPU memory、恢复、更新权重和退出。主线不是“有哪些命令”,而是每个动作改变了哪些 owner 的状态:API process、EngineCore、GPU workers、preload daemon、外部 Gateway/Kubernetes 分别掌握什么。

可执行命令和故障排查见 vllm-production-operations-runbook;单次请求在 engine 内的调用链见 vllm-gpu-execution-path。

版本与证据边界

核验日期:2026-10-12。

证据面 固定版本 本页用法
Stable release v0.31.0,2026-10-05 发布 Sleep、Preload、IPC loader 等 release-documented 合同
Upstream main c85616efc6f0eaa50ca1f1a09c32368aedffd3d8 main-documented 增量能力和最新源码形状
历史 wiki Source src-vllm-architecture 2026-09 本地代码快照,不覆盖本页的 0.31.0 判断

本页采用五种证据标签:

固定源码入口

生命周期环节 v0.31.0 固定入口
Sleep 使用说明 docs/features/sleep_mode.md
Preload 使用说明 docs/features/preload.md
Scheduler/worker dispatch vllm/v1/engine/core.py / gpu_worker.py
Sleep backend sleep_mode_backend.py
Preload CLI/daemon preload.py / daemon.py
IPC loader ipc_loader.py
Dev Sleep API sleep/api_router.py

Lifecycle 状态机

CREATED
   │ process/distributed init
   ▼
LOADING
   ├── disk/object-store loader
   └── preload daemon → ipc_cache map/copy
   │ weights constructed and validated
   ▼
WARMING
   │ memory profile · KV allocation · kernel warmup · optional graph capture
   ▼
READY / SERVING
   │ external admission off · request policy chosen
   ▼
DRAINING / PAUSED
   ├── Sleep L0 ─────────────► PAUSED, memory stays resident
   ├── Sleep L1 ─────────────► SLEEPING, weights CPU-backed, KV discarded
   ├── Sleep L2 ─────────────► SLEEPING, weights/KV discarded
   └── process shutdown ─────► STOPPED

SLEEPING
   │ wake tags / reload / allocate KV
   ▼
WAKING
   ├── all ranks succeed + warm check ──► READY
   └── mismatch/OOM/rank failure ───────► FAILED → rollback/restart

状态机有两个层次:vLLM engine 的真实 scheduler/memory state,以及 external-control-plane 对入口的 serving eligibility。Engine 进入 Sleep 不会自动修改 Kubernetes readiness 或 Gateway endpoint membership;外部系统必须先停止新流量并在恢复验证后重新放行。

Process / Engine / Worker / Daemon 所有权

[API Server process]
HTTP/gRPC · tokenizer/request preprocessing · client streams
        │ EngineCoreClient
        ▼
[EngineCore process]
Scheduler queues · Request state · KV logical ownership · pause state
        │ executor RPC/direct calls
        ▼
[GPU Worker rank(s)]
model object · weights · KV tensors · CUDA Graph · device allocator
        │ collectives
        └══► peer TP/PP/DP/EP ranks

[Preload daemon process per GPU]
post-quantized rank shard · CUDA IPC handles · Unix socket · fingerprint
        │ map/copy weights only
        └══► GPU Worker

[External control plane]
Pod/process lifecycle · readiness · routing membership · replica replacement
        ··► API/Engine/Daemon actions

关键边界:

普通启动与 Preload 启动

普通加载

checkpoint / model repository
        │ download/read
        ▼
each worker builds model
        │ load rank shard
        │ quantization post-processing
        ▼
engine-owned GPU weights
        │ warmup/profile/KV allocation
        ▼
READY

这是默认所有权:weights由engine worker allocation持有,process退出就释放。

vllm preload + ipc_cache

release-documented(v0.31.0):

vllm preload launcher
  └── daemon per local GPU/rank
       checkpoint → shard → post-quantize → daemon GPU allocation
                                          │ export CUDA IPC handles
                                          │ bind private Unix socket when ready
                                          ▼
vllm serve --load-format ipc_cache
  └── worker builds meta model
       ├── compare weight fingerprint + GPU UUID
       ├── zero_copy: map daemon tensors
       └── copy: clone to engine allocation; daemon releases cache

Preload优化的是engine restart的weight load与post-processing。它不保留KV、请求、CUDA Graph executable、scheduler queue或客户端连接。Fingerprint覆盖checkpoint content metadata、model architecture、dtype、quantization、parallel layout、revision与vLLM version;不匹配时默认fallback到disk,除非显式关闭fallback。

Warmup 与 Ready

weights available
   │
   ├── determine/profile usable GPU memory
   ├── allocate KV cache / workspace
   ├── initialize attention and custom-op backends
   ├── compile/JIT/download kernels as configured
   ├── dummy/profile runs
   └── optional CUDA Graph capture / FlashInfer autotune
            │
            ▼
engine can execute smoke request
            │
            ├··► process health
            ├··► engine readiness
            ├··► Kubernetes readiness
            └··► router membership

“Process alive”只说明进程未退出;“Ready”至少应包含model/weights可用、所有必要ranks可通信、KV/runner初始化完成且engine允许调度。Preload daemon的/health只表示daemon ranks已缓存并serving,不等价于engine ready。

main-documented:固定 main 文档还描述可选CUDA Graph memory offload和实验性NCCL communicator suspend。它们不是v0.31.0本页基础矩阵的默认假设,采用前必须核验目标main/release、backend与driver/NCCL版本。

Drain 与 Pause

external router
   │ remove endpoint / readiness=false
   ▼
stop new admission
   │
   ├── abort: terminate accepted requests
   ├── wait: stop new work and drain existing requests
   └── keep: pause all; retained requests need safe recomputation/resume semantics
   │
   ▼
EngineCore scheduler reaches requested pause boundary
   │ output queue / transfer / worker work safe
   ▼
memory lifecycle action may begin

release-documented:当前Sleep API的mode决定已有请求处理方式,具体in-process/async engine限制需按调用路径验证。运维系统不能在仍有GPU work或P/D transfer访问同一allocation时直接free memory。

已向client发送token的stream若因abort/restart中断,不能假设可在另一实例透明续写;参见 llm-serving-reliability。

Sleep Level 0/1/2

release-documented:

Level 0
  scheduler: PAUSED
  GPU weights: keep
  KV physical memory: keep (unless separately release_kv_cache_memory)
  process: alive

Level 1
  scheduler: PAUSED
  GPU weights: release; contents backed in CPU RAM
  KV cache: discard
  intended wake: restore same model weights + allocate fresh KV

Level 2
  scheduler: PAUSED
  GPU weights: discard (selected buffers may be CPU-saved)
  KV cache: discard
  intended wake: allocate weights region → load/update weights → allocate KV

Level 1要求足够host memory保存weights。Level 2降低host backup压力,适合不同权重或RLHF更新,但不能仅调用full wake就假定旧weights自动回来;文档路径要求partial wake weights、reload,再wake KV。

只释放KV是独立路径:先完成Level 0 pause且executor memory全部resident,再release_kv_cache_memory(),最后wake_up(tags=["kv_cache"])。保留的request需要重算被丢弃的KV,不能沿用旧block内容。

Partial Wake 与 Reload Weights

Sleep Level 2
   │ old weights/KV absent
   ▼
wake_up(tags=["weights"])
   │ allocate weight regions only; scheduler remains paused/is_sleeping
   ▼
collective reload/update on every worker rank
   │ verify version/layout/checksum + all ranks success
   ▼
wake_up(tags=["kv_cache"])
   │ allocate/init fresh KV capacity
   ▼
optional warmup/smoke
   │
wake scheduling / external readiness=true

Tags weights、kv_cache、scheduling 是不同资源/控制面。Partial wake期间is_sleeping仍应视为true,直到所有必需allocation恢复且scheduler可运行。Multi-rank update必须整体成功;单rank failure时整个serving group退出readiness并rollback或restart,不能继续接流量。

Preload Cache Modes

release-documented:

Mode Weight owner Engine行为 Daemon行为 重启收益 Sleep关系
zero_copy(默认) preload daemon 直接映射daemon CUDA allocations engine生命周期内保持alive 最快,额外copy/显存副本最少 不兼容CuMemAllocator weight offload
copy engine worker clone到自己的GPU allocation handoff后释放cache 免disk/post-process但仍有GPU copy ownership更适合engine管理,仍需目标版本验证

[!warning] zero_copy不能与Sleep Mode的weight offload组合。IPC weights属于daemon allocation,不属于engine的Sleep allocator;尝试把daemon-owned权重当作engine-owned释放会破坏ownership合同。

zero_copy:
Daemon GPU weights ══ CUDA IPC mapping ══► Engine tensor views
      │ daemon exits → mappings/lifetime at risk
      └── Sleep allocator does not own these allocations

copy:
Daemon GPU weights ══ GPU copy ══► Engine-owned weights
      └── release daemon cache       └── normal engine ownership

v0.31.0 Preload支持CUDA/ROCm、TP/EP/DP及跨节点组合,但daemon不支持PP;CUDA IPC仍是node-local,每个node只服务自己的local GPU shards。具体quantization必须声明支持post-processed weights。

LoRA 生命周期

base engine READY
   │ add/load LoRA request
   ▼
adapter validate/load → worker LoRA manager → adapter resident/available
   │ requests reference adapter identity
   ▼
in-flight adapter requests complete
   │ remove/unload after no unsafe users
   ▼
adapter capacity returned

LoRA preload在这里指add_lora提前加载adapter,和CLI vllm preload weight-cache daemon不是同一功能。Adapter registry/residency通常随engine process;restart/scale-out后由external-control-plane重新声明/加载,不能假设新replica继承内存状态。

Sleep与LoRA的保留行为依实际allocator/tag/backend和版本,属于integration-dependent;运维前应通过目标配置验证adapter在wake后仍可用或显式重载。

Shutdown 与 Restart

remove from external routing
   → stop admission
   → drain/abort according to request contract
   → wait output queues and async transfers
   → unregister/close endpoints
   → stop workers and collectives
   → release KV/weights/graphs/workspaces
   → unlink sockets / terminate daemon if desired
   → process STOPPED

restart
   → choose disk or preload path
   → warm/readiness/smoke
   → re-enter routing

external-control-plane负责Pod termination ordering、grace period、replacement和Gateway候选传播。SIGTERM不会自动证明client streams已完成;termination grace必须覆盖drain与engine teardown,超时后的强杀应作为显式失败计数。

若使用zero_copy Preload,engine restart期间daemon应继续存活;若要释放GPU,则daemon也必须终止。Daemon SIGINT/SIGTERM会终止所有rank、unlink sockets并释放其weights。

资源状态矩阵

状态/动作 Scheduler In-flight requests GPU weights CPU backup KV cache CUDA Graph NCCL Process/Daemon
Normal serve running active engine/daemon resident optional resident captured/eager active engine alive
Drain no new external traffic finish/abort policy resident unchanged resident resident active alive
Sleep L0 paused mode-dependent resident unchanged resident resident active alive
L0 + release KV paused retained work must recompute resident unchanged discarded resident active alive
Sleep L1 paused safe boundary required released full weights retained discarded backend/flag-dependent default remains; main option may suspend alive
Sleep L2 paused safe boundary required discarded selected buffers/frozen params only discarded backend/flag-dependent default remains; main option may suspend alive
Partial weight wake paused none should run allocated/reloaded consumed/replaced absent not ready rank-consistent alive, still sleeping
Preload zero-copy separate none daemon-owned none none autotune cache only daemon group as configured daemon must live
Preload copy handoff engine loading none engine-owned after clone none none later warmup engine-owned daemon cache released
Shutdown stopped drained/failed released released released released destroyed exited

CUDA Graph/NCCL列故意标出backend/flag差异:不要用一个“Sleep释放率”推断某块memory必然被释放。

失败与恢复边界

失败 可见信号 安全行为
Preload daemon未ready/socket缺失 connect timeout、daemon health 503 默认disk fallback并告警;若禁止fallback则保持unready
Fingerprint/GPU UUID mismatch cache unusable/mismatch log 拒绝错误mapping,fallback或fail
Sleep前仍有unsafe work pause/drain未完成、transfer outstanding 不进入memory release,等待或abort
L1 CPU RAM不足 offload OOM/host pressure 保持实例隔离,恢复或改用L2/restart
Wake OOM allocation/resume失败 whole group unready,rollback/restart
一个rank失败 collective/RPC timeout、rank error 所有ranks退出routing,不允许partial service
Reload layout/version不匹配 missing/mismatched tensors、collective error 不恢复scheduling,回滚旧revision或restart
Daemon在zero-copy engine期间退出 IPC allocation lifetime failure/engine error 隔离engine并restart;不能把mapping当作durable weights
Stream已输出后restart truncated/reset response 返回中断,不透明replay

恢复的共同条件是owner确认状态,而不是只看外部Pod仍为Running。

外部控制面接口

Gateway / Router
  ··► endpoint admission on/off
Kubernetes / Operator
  ··► Pod lifecycle · readiness · rollout · grace period
Metrics / Observability
  ··► queue · in-flight · sleep state · memory · errors
             │
             ▼
vLLM lifecycle action
  ──► pause/drain/sleep/wake/reload/shutdown
             │ verified state
             └··► readiness/membership update

model-serving-operator 或 AIBrix/Dynamo/llm-d 可以编排这些动作,但不能改变vLLM内部ownership:它们应把engine state反馈到readiness,再决定扩缩/rollout。完整操作顺序见 vllm-production-operations-runbook。