vLLM V1 用户指南:新一代统一核心架构的调度、采样语义与特性支持全景
【免费下载链接】vllmA high-throughput and memory-efficient inference and serving engine for LLMs项目地址: https://gitcode.com/GitHub_Trending/vl/vllm
本文基于 vllm 仓库 的官方 V1 用户指南撰写,结合仓库源码(调度器、配置解析等)补充实现细节,帮助读者快速理解 vLLM V1 相较 V0 的行为差异、统一调度器的工作原理、Logprobs 语义变化,以及各硬件/模型/特性在 V1 上的支持状态与迁移策略。读完本文,你将掌握 V1 引擎的关键参数(
--scheduling-policy、--logprobs-mode)、知晓哪些 V0 能力已被移除及替代方案,并能据此规划模型服务与功能的升级路径。
V1 是什么:一次聚焦核心引擎的架构重构
vLLM V0 成功支持了广泛的模型与硬件,但随着新特性独立演进,系统逐渐变得复杂,新能力接入困难,技术债务随之累积。V1 正是为了提供一个更简洁、统一、易于维护与二次开发的核心框架而诞生的架构升级。
V1 的策略并非推倒重来:它完整保留了 V0 中稳定且被验证过的组件(模型实现、GPU kernels、工具函数等),同时围绕几个核心子系统进行了显著重构,涵盖:
- 调度器(Scheduler)
- KV Cache 管理器
- Worker
- 采样器(Sampler)
- API Server
具体而言,V1 的目标是(见 docs/usage/v1_guide.md):
| 目标 | 含义 |
|---|---|
| 简单、模块化、易于修改 | 提供一个“易 hack”的代码库,降低二次开发门槛 |
| 高性能、近零 CPU 开销 | 尽量消除调度循环中的 CPU 瓶颈 |
| 统一整合关键优化 | 将多项优化组合进一个统一架构,避免特性各自为政 |
| 零配置默认开启 | 默认启用特性与优化,用户开箱即得最佳体验 |
从官方描述看,升级到 V1 核心引擎后尤其在长上下文场景有显著性能提升(具体基准数据当时标注为 “To be added”,仍在补充中,本仓库不包含该基准数据)。V1 架构细节可进一步阅读 docs/design/arch_overview.md 与 docs/design/optimization_levels.md。
需要注意,vLLM 官方已宣布彻底弃用 V0(相关 RFC 编号 #18571)。因此,本文档所描述的差异与限制,本质上就是当前 vLLM 的默认行为基线;若你的用例仍依赖 V0 特性,需要关注下文的“已移除功能”清单。
与 V0 的主要行为差异
V1 重构核心系统后,在若干行为上与 V0 存在明显不同,直接关系到用户可观察到的吞吐、显存与采样输出。
Chunked Prefill:默认开启
Chunked Prefill(分块预填充)允许把超长 prompt 切成多个块分批参与调度,避免因单条超长 prompt 长时间独占 batch 而阻塞 decode。
- V0:chunked prefill 基于模型特征有条件地启用;
- V1:只要条件允许就默认启用。
这在源码中有直接印证:vllm/config/scheduler.py 中SchedulerConfig.enable_chunked_prefill的默认值即为True,并提供了max_num_batched_tokens(默认 2048)控制每轮迭代最多处理的 token 数。同时要注意一个例外:is_encoder_decoder(编码器-解码器模型)为真时,V1 会在__post_init__中强制关闭 chunked prefill 与 prefix caching(见 vllm/config/scheduler.py)。
CUDA Graphs:捕获阶段占用更多内存
CUDA graph 能将一整个 GPU kernel 序列捕获并重放,从而压低 host 侧启动开销。V1 中CUDA graph 捕获所需显存比 V0 更大。在显存受限、使用 CUDA graph 时报 OOM 的场景,可以考虑设置--enforce-eager关闭 CUDA graph(源码注释见 vllm/config/model.py),以 eager 模式换取更低的显存占用。
Logprobs 的语义变化
这是 V1 最容易被忽视、却会直接改变返回结果的差异点。
Logprobs 计算时机:默认返回“原始值”
在 V0 中,返回的 logprobs 通常经过采样后处理;而 V1 默认在拿到模型原始输出后立即返回 logprobs(即尚未应用 temperature 缩放、penalty 调整等 logits 后处理)。因此默认情况下,返回的 logprobs并不反映最终采样时使用的概率。这对基于 logprob 做二次计算(如打分、重排)的用户至关重要。
通过--logprobs-mode参数可以调整该行为,共支持四种模式(见 docs/usage/v1_guide.md):
| 模式 | 返回内容 | 典型用途 |
|---|---|---|
raw_logprobs(默认) | 模型原始输出经 softmax 归一化后的 logprobs,未经任何 logits processor(如 bad words 过滤)处理 | 分析模型“真实”的原始分布 |
processed_logprobs | 应用全部 processor(含 temperature、top_k/top_p、penalty)之后的最终 logprobs | 复现采样阶段实际使用的概率 |
raw_logits | 未经后处理的原始 logits 值 | 需要自己接管后续归一化/采样的场景 |
processed_logits | 全部后处理完成后的 logits 值 | 精确复现最终采样打分 |
在源码层面,四种取值由LogprobsMode联合类型定义,ModelConfig.logprobs_mode默认值为"raw_logprobs"(见 vllm/config/model.py、vllm/config/model.py);CLI 参数--logprobs-mode在 vllm/engine/arg_utils.py 注册并透传到ModelConfig。另外源码注释特别说明:对于 prompt_logprobs 而言,processed_*与raw_*结果完全相同——因为 prompt token 不经过采样 processors。
Prompt Logprobs 与 Prefix Caching 的相互作用
V1 支持在开启 prefix caching 的同时请求 prompt logprobs,但V1 不再缓存 logprobs。这意味着:一旦某条请求要求 prompt logprobs,引擎会忽略前缀缓存、重新对完整 prompt 执行 prefill,以生成所需的 logprobs。换言之,“要求 prompt logprobs”与“命中 prefix cache 省算力”在当前 V1 中不可兼得,代价是额外的 prefill 计算。
V1 特性支持状态总览
对于每一项特性,vLLM V1 的支持程度分为三种状态:
- 🟢Functional(可用):功能完整,且带有与 V0 相当或更优的优化;
- 🟡In Progress(进行中):已规划进入 V1,存在公开 PR/RFC;
- 🔴Removed(已移除):已从 V1 移除,仅在出现强烈需求时才考虑重新引入。
统一调度器:V1 一切特性的地基
在展开各特性状态前,需要先理解 V1 调度模型的一个核心变化:V1 的统一调度器把 prompt token 与 output token 同等对待,用一个简单的字典(例如{request_id: num_tokens})为每个请求动态分配固定的 token 预算(token budget),从而让 chunked prefill、prefix caching、speculative decoding 等特性可以共存,不再需要 prefill 与 decode 阶段之间严格的界限划分(原文见 docs/usage/v1_guide.md)。这也解释了为何移除 KV cache swapping(见下文)不会引发 V0 时代那些抢占问题。
调度策略:FCFS 与优先级调度
V1 调度器支持多种调度策略:
- FCFS(First-Come, First-Served):按请求到达顺序处理;
- Priority(优先级调度):按请求被赋予的优先级处理,优先级数值越小越先被调度,到达时间作为平局打破依据。
两者通过--scheduling-policy参数配置(fcfs或priority)。
实现证据清晰可见:vllm/config/scheduler.py 中SchedulerConfig.policy字段默认"fcfs",SchedulerPolicy类型即Literal["fcfs", "priority"];CLI 参数注册在 vllm/engine/arg_utils.py。在 vllm/v1/core/sched/scheduler.py 中,waiting 队列通过create_request_queue(self.policy)按所选策略构造,抢占(preemption)时选取待抢占请求也依据(r.priority, r.arrival_time)排序(见 vllm/v1/core/sched/scheduler.py),与文档“低数值高优先、时间戳平局”的描述完全吻合。
特性支持矩阵
| 特性 | 状态 |
|---|---|
| Prefix Caching(前缀缓存) | 🟢 Functional |
| Chunked Prefill(分块预填充) | 🟢 Functional |
| LoRA | 🟢 Functional |
| Logprobs Calculation(logprobs 计算) | 🟢 Functional |
| FP8 KV Cache | 🟢 Functional |
| Spec Decode(投机解码) | 🟢 Functional |
| Prompt Logprobs with Prefix Caching | 🟢 Functional |
| Structured Output 替代后端 | 🟢 Functional |
| Concurrent Partial Prefills(并发部分预填充) | 🟡 In Progress |
| best_of | 🔴 Removed |
| Per-Request Logits Processors(按请求 logits 处理器) | 🔴 Removed |
| GPU ↔ CPU KV Cache Swapping | 🔴 Removed |
| Request-level Structured Output Backend(按请求结构化输出后端) | 🔴 Removed |
硬件与模型支持矩阵
硬件平台
截至本指南撰写时,以下硬件平台在 V1 上均为 🟢 功能可用:
| 硬件 | 状态 |
|---|---|
| NVIDIA | 🟢 |
| AMD | 🟢 |
| Intel GPU | 🟢 |
| TPU | 🟢 |
| CPU | 🟢 |
此外,更多硬件平台可以通过**插件(plugin)**方式接入 V1(例如 vllm-ascend、vllm-spyre、vllm-gaudi、vllm-openvino 等社区/厂商插件仓库),具体支持情况以对应插件仓库为准。插件机制本身是 V1 官方推荐的扩展路径,机制说明见 docs/design/plugin_system.md。
模型类别
| 模型类型 | 状态 |
|---|---|
| Decoder-only Models(仅解码器) | 🟢 |
| Encoder-Decoder Models(编码器-解码器) | 🟢(Whisper),🔴(其余) |
| Pooling Models(池化/嵌入模型) | 🟢 |
| Mamba Models(状态空间模型) | 🟢 |
| Multimodal Models(多模态模型) | 🟢 |
Pooling Models:已完整支持
Pooling 模型(embedding、classify、reward 等)在 V1 中已完整支持,并且last-pooling 类模型现已支持 prefix caching 与 chunked prefill;官方仍在推进更多类别 pooling 模型对这两项特性的支持。
Mamba Models:状态空间与混合架构
使用选择性状态空间机制(替代标准 Transformer attention)的模型均受支持,典型实现包括:
Mamba2ForCausalLM、MambaForCausalLM、FalconMambaForCausalLM;- 混合架构模型(Mamba-2/Mamba-1 层与标准 attention 层混搭):
Zamba2ForCausalLM、NemotronHForCausalLM、FalconH1ForCausalLM、GraniteMoeHybridForCausalLM、JambaForCausalLM; - 使用非 Mamba 机制的其他混合模型,如
Lfm2ForCausalLM。
需要特别留意:以上所有 Mamba 类模型目前均不支持 prefix caching。若你的工作负载依赖前缀缓存收益,选用这类模型前需要评估重新计算 prefix 的开销。
Encoder-Decoder Models:Whisper 原生,其余走插件
- Whisper:V1 原生支持。
- BART / Florence-2:
BartForConditionalGeneration、Florence2ForConditionalGeneration通过官方bart-plugin插件支持。 - 其他编码器-解码器模型(如
MllamaForConditionalGeneration):官方建议参照同样的模式,通过 插件系统 自行实现支持,而不是合入主仓库。
已移除的功能与迁移建议
架构大重构必然伴随取舍。V1 移除了若干 V0 遗留特性,若你的服务依赖其中任何一项,请阅读对应替代方案。
采样相关
best_of(已移除):V0 中用于对同一 prompt 并行生成多个候选并择优返回。因使用率有限而被移除(相关 RFC #13361)。需要“多次采样取最优”时,可在应用侧自行发起多次请求实现等价逻辑。
Per-Request Logits Processors(已移除):V0 允许在单条请求上挂载自定义处理函数来调整 logits;V1 移除了按请求传入的方式,改为支持全局 logits processors——即服务启动时一次性设置、对所有请求生效(相关 RFC #17799)。如果你的代码在请求级传入了自定义 logits processor,需要改为全局注册。
KV Cache 相关
GPU ↔ CPU KV Cache Swapping(已移除):V0 在显存不足时通过把 KV cache 块换出到 CPU 内存来缓解压力。V1 由于核心架构大幅简化,不再需要通过 KV cache swapping 来处理请求抢占(preemption)——配合前文所述统一调度器与 token budget 机制,抢占路径被重新设计。若你此前依赖swap_space之类的配置调优,需要重新评估其在 V1 下的作用。
结构化输出相关
Request-level Structured Output Backend(已移除):V0 允许在单条请求上指定结构化输出后端(如选择 outline 或 guidance)。V1 改为支持全局的替代后端(alternative backends:outlines、guidance)并带有回退机制,即结构化输出后端在服务级别统一配置。
快速上手建议与最佳实践
结合以上差异,为 V1 迁移场景总结如下可执行要点:
- 升级前先核对特性依赖:对照“特性支持矩阵”逐一确认所用能力是否处于 🟢;若命中 🔴 项(best_of、请求级 logits processors、请求级结构化输出后端、KV swap),先改造应用侧逻辑;
- 正确选择 logprobs 语义:需要与“采样实际概率”一致的 logprob 时,设置
--logprobs-mode processed_logprobs;需要模型原始打分则保持默认raw_logprobs; - 按负载配置调度策略:混合了不同 SLA 的请求时,可使用
--scheduling-policy priority,配合请求级 priority 字段让关键请求优先、其余按到达顺序兜底; - 留意显存与长上下文:长上下文场景是 V1 收益最明显之处,但 CUDA graph 捕获会占用更多显存,若 OOM 可尝试
--enforce-eager;同时默认开启的 chunked prefill 会按max_num_batched_tokens切分大 prompt,相关参数在 docs/configuration/engine_args.md 有完整说明; - Mamba 与 prefix caching 不可兼得:选用 Mamba/混合状态空间模型前评估 prefix 重算成本;
- 结构化输出、编码器-解码器扩展走插件:需要 BART/Florence-2 之外的 encoder-decoder 模型时,按 插件系统 的模式自行实现,不依赖主仓库内置支持。
本文档在官方仓库中定位为living user guide(持续更新的活文档)——V1 作为默认引擎的推进过程中,会有越来越多特性被点亮或调整,docs/usage/v1_guide.md 会随之持续更新;同时可结合 docs/design/arch_overview.md 了解 V1 整体设计,结合 vllm/config/scheduler.py 与 vllm/v1/core/sched/scheduler.py 深入研读调度实现,跟踪最新的支持状态与限制。
【免费下载链接】vllmA high-throughput and memory-efficient inference and serving engine for LLMs项目地址: https://gitcode.com/GitHub_Trending/vl/vllm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考