vLLM-01-Engine模块-概览
模块职责
Engine 模块是 vLLM 的核心引擎层,负责:
- 接收和管理推理请求的生命周期
- 协调输入处理(Processor)、核心执行(EngineCore)和输出处理(OutputProcessor)
- 提供离线推理(LLMEngine)和在线服务(AsyncLLMEngine)两种模式
- 管理引擎的初始化、配置和关闭流程
- 收集和报告性能指标
输入与输出
输入
- 请求信息:
request_id(唯一标识)、prompt(文本或 token IDs)、sampling_params(采样参数) - 配置信息:
VllmConfig(包含模型、缓存、并行等配置) - 可选参数:
lora_request(LoRA 适配器)、trace_headers(追踪信息)、priority(优先级)
输出
- RequestOutput:包含生成的 token、logprobs、完成状态
- PoolingRequestOutput:用于 embedding 任务
- 性能指标:吞吐量、延迟、缓存命中率等
上下游依赖
上游(调用方)
vllm.entrypoints.llm.LLM:离线推理接口vllm.entrypoints.openai.api_server:OpenAI API Server- 用户应用程序
下游(被调用)
Processor:输入处理,tokenization 和多模态处理EngineCore:核心执行循环,调度和模型执行OutputProcessor:输出处理,detokenizationExecutor:模型执行器,驱动 Worker
生命周期
初始化阶段
- 解析和验证配置(
VllmConfig) - 初始化 tokenizer
- 创建
Processor(输入处理器) - 创建
OutputProcessor(输出处理器) - 创建
EngineCore(核心执行器) - 初始化统计日志管理器(可选)
运行阶段
- 接收请求(
add_request) - 处理输入(
Processor.process_inputs) - 加入调度队列
- 执行引擎循环(
step) - 返回结果(流式或批量)
关闭阶段
- 等待所有请求完成
- 释放 EngineCore 资源
- 销毁分布式进程组(如果有)
- 记录最终统计信息
架构图
flowchart TB
subgraph API["API 层"]
LLM[LLM 类]
AsyncAPI[Async API]
end
subgraph Engine["LLMEngine"]
Processor[Processor<br/>输入处理器]
EngineCore[EngineCore<br/>核心执行]
OutputProc[OutputProcessor<br/>输出处理器]
end
subgraph Core["EngineCore 内部"]
Scheduler[Scheduler<br/>调度器]
Executor[Executor<br/>执行器]
end
subgraph Support["支持组件"]
Tokenizer[Tokenizer]
Logger[StatLogger<br/>统计日志]
Tracer[OpenTelemetry<br/>追踪]
end
LLM -->|add_request| Engine
AsyncAPI -->|add_request| Engine
Engine -->|tokenize| Tokenizer
Engine -->|process_inputs| Processor
Processor -->|EngineCoreRequest| EngineCore
EngineCore -->|schedule| Scheduler
EngineCore -->|execute| Executor
EngineCore -->|outputs| OutputProc
OutputProc -->|detokenize| Tokenizer
OutputProc -->|RequestOutput| Engine
Engine -->|返回| LLM
Engine -.记录指标.-> Logger
Engine -.追踪.-> Tracer
架构说明
1. 图意概述
Engine 模块采用三层处理模式:输入处理(Processor)→ 核心执行(EngineCore)→ 输出处理(OutputProcessor)。请求从 API 层进入 LLMEngine,经过 tokenization 后提交给 EngineCore,EngineCore 通过 Scheduler 调度和 Executor 执行,最后通过 OutputProcessor 完成 detokenization 并返回结果。
2. 关键接口
LLMEngine 核心方法:
add_request(request_id, prompt, params): 添加新请求abort_request(request_ids): 取消请求step(): 执行一个引擎步骤get_metrics(): 获取性能指标
Processor 接口:
process_inputs(request_id, prompt, params): 处理输入,返回EngineCoreRequest
EngineCore 接口:
add_request(request): 添加请求到调度队列step(): 调度并执行一批请求abort_requests(request_ids): 取消请求
OutputProcessor 接口:
add_request(request, prompt_str, parent_req, index): 注册请求process_outputs(outputs): 处理输出,返回RequestOutput
3. 边界与约束
并发限制:
- 最大并发请求数:
max_num_seqs(默认 256) - 最大批次 token 数:
max_num_batched_tokens(默认 8192) - 受 KV 缓存容量限制
超时机制:
- 请求级超时:通过
arrival_time计算 - 引擎循环超时:
POLLING_TIMEOUT_S = 2.5秒
幂等性:
- 请求通过全局唯一
request_id标识 - 重复添加相同
request_id会被拒绝 - 取消操作幂等(多次取消同一请求无副作用)
顺序保证:
- 单个请求的输出按生成顺序返回
- 不同请求之间无顺序保证(并行执行)
4. 异常处理
输入异常:
- Tokenization 失败:抛出
ValueError - 无效参数:抛出
ValidationError - 超长序列:抛出或截断(根据配置)
执行异常:
- Worker 崩溃:整个引擎不可用,需重启
- OOM:触发抢占或拒绝新请求
- 超时:返回部分结果,标记
finished=False
降级策略:
- 禁用 CUDA Graph:提高稳定性
- 减小批次大小:降低内存压力
- 禁用 Prefix Caching:简化调度
5. 性能特性
热路径优化:
step()方法是性能关键路径- Processor 和 OutputProcessor 设计为轻量级
- EngineCore 通过 CUDA Graph 优化 kernel launch
- 输出处理与下一个 step 可并行
容量规划:
- KV 缓存容量 =
num_gpu_blocks × block_size × 2 × num_layers × num_heads × head_dim - 典型配置:Llama-70B,fp16,90% GPU 内存利用率 → ~2000 个 block(32K tokens)
可扩展性:
- 支持张量并行(TP):线性扩展(通信开销 <10%)
- 支持流水线并行(PP):近线性扩展(气泡 <15%)
- 支持数据并行(DP):完全独立,无通信
6. 兼容性
版本兼容:
- V0 → V1 API 保持兼容
EngineArgs→VllmConfig平滑迁移LLM类接口稳定
硬件兼容:
- CUDA: SM 7.0+(V100+)
- ROCm: gfx908+(MI100+)
- CPU: AVX2+
- TPU: v5e+
核心算法与流程
引擎循环(step)
def step(self) -> list[RequestOutput]:
# 1. 调度:选择本批次要处理的请求
scheduler_output = self.scheduler.schedule()
# 2. 执行:运行模型前向传播和采样
model_output = self.executor.execute_model(scheduler_output)
# 3. 更新:更新请求状态
engine_outputs = self.scheduler.update_from_output(
scheduler_output, model_output)
# 4. 输出处理:detokenization 和结果封装
request_outputs = self.output_processor.process_outputs(engine_outputs)
return request_outputs
算法说明:
- 目的:每个 step 执行一次模型前向传播,生成一批 token
- 输入:调度器状态(waiting/running 队列)
- 输出:本 step 生成的所有 RequestOutput
- 复杂度:O(n) for n = 当前运行请求数;实际瓶颈在模型前向传播
请求生命周期管理
def add_request(self, request_id, prompt, params):
# 1. 输入处理
prompt_str, request = self.processor.process_inputs(
request_id, prompt, params, ...)
# 2. 注册到输出处理器
self.output_processor.add_request(request, prompt_str, ...)
# 3. 提交到 EngineCore
self.engine_core.add_request(request)
算法说明:
- 目的:接收用户请求,完成预处理并加入调度队列
- 输入:原始 prompt 和参数
- 输出:无(异步操作)
- 复杂度:O(m) for m = prompt 长度(tokenization)
输出流式处理
def process_outputs(self, outputs: list[EngineCoreOutput]) -> list[RequestOutput]:
for output in outputs:
# 1. detokenize
text = self.tokenizer.decode(output.new_token_ids)
# 2. 构造 RequestOutput
request_output = RequestOutput(
request_id=output.request_id,
outputs=[CompletionOutput(text=text, ...)],
finished=output.finished
)
yield request_output
算法说明:
- 目的:将 token IDs 转换为文本,封装为 RequestOutput
- 输入:EngineCoreOutput(包含 token IDs、logprobs 等)
- 输出:RequestOutput(包含文本、状态等)
- 复杂度:O(k) for k = 新生成的 token 数
总结
Engine 模块是 vLLM 的门面和协调者,负责请求的完整生命周期管理。通过 Processor、EngineCore、OutputProcessor 三层架构,实现了输入处理、核心执行、输出处理的解耦。V1 架构进一步优化了引擎循环,支持多进程模式,提升了吞吐量和稳定性。