Skip to content

架构概览 — 练习

练习 1:绘制请求流转图

根据你对架构的理解,绘制一个请求从 vllm serve 启动到返回第一个 token 的完整流程图。

参考答案

关键步骤:

  1. FastAPI 接收 HTTP 请求,解析为 ChatCompletionRequest
  2. AsyncLLM.generate() 将请求通过 InputProcessor tokenize
  3. 通过 EngineCoreClient(ZMQ)发送 EngineCoreRequestEngineCore
  4. Scheduler.schedule() 决定是否进行 prefill
  5. Executor.execute_model() 分发到 GPU Worker
  6. ModelRunner 执行模型前向传播
  7. OutputProcessor 将 logits 转换为 token
  8. 通过 ZMQ 返回给 AsyncLLM,通过 SSE 流式返回给客户端

练习 2:配置系统分析

阅读 vllm/config/vllm.py,回答以下问题:

  1. VllmConfig 包含哪些子配置?它们之间的依赖关系是什么?
  2. ModelConfig 如何决定使用哪个模型实现?
  3. ParallelConfig 如何影响 Worker 的创建?
参考答案
  1. VllmConfig 是聚合配置,包含 model_configparallel_configscheduler_configcache_configcompilation_config 等 30+ 子配置。依赖关系:cache_config 依赖 model_config(block_size 由模型头数决定),scheduler_config 依赖 cache_config(max_num_seqs 受缓存大小限制)。

  2. ModelConfig 通过 architectures 字段匹配 ModelRegistry 中注册的模型类。每个 HuggingFace 模型配置中声明了 architectures,vLLM 以此为键查找对应实现。

  3. ParallelConfig 定义了 tensor_parallel_sizepipeline_parallel_size 等。MultiProcExecutor 据此创建对应数量的 Worker 进程,每个 Worker 绑定到特定的 GPU。

练习 3:进程模型分析

分析 vLLM 的多进程模型:

  1. EngineCore 为什么运行在独立进程中?
  2. EngineCoreClient 如何实现进程间通信?
  3. Worker 进程如何与 EngineCore 交互?
参考答案
  1. 独立进程可以避免 Python GIL 对调度和推理的竞争。API 服务器处理网络 I/O 不影响 EngineCore 的调度循环。同时支持多前端(多个 API server)连接到同一个 EngineCore。

  2. EngineCoreClient 使用 ZMQ 进行 IPC。支持两种模式:SYNC(同步调用)和 ASYNC(异步非阻塞)。通过 ZMQ 的 DEALER/ROUTER 模式实现请求-响应匹配。

  3. Worker 不直接与 EngineCore 交互。EngineCore 通过 Executor 发送 SchedulerOutput 给 Worker,Worker 执行后返回 ModelOutput。Executor 负责进程间通信(pipe 或 Ray)。

拓展挑战

  • 阅读 vllm/v1/engine/core.pyrun_loop 方法,理解 EngineCore 的主循环逻辑
  • 对比 V0 和 V1 的 AsyncLLMEngine 实现,分析架构改进带来的性能提升
  • 研究 vllm/entrypoints/openai/api_server.py 的中间件链,理解限流、认证等机制