[FIXME][EP06] vLLM 源码讲解直播笔记

EP06: vLLM v1 仙人指路

直播回看链接:https://www.youtube.com/watch?v=6AcgEPmpHIc

特别鸣谢:组织者@月球大叔, 主讲人@Du Kuntai, 飞行嘉宾@YM

vLLM官方博客:https://blog.vllm.ai/2025/01/27/v1-alpha-release.html

💥 1. Why v1 ? (Motivation)

  • vLLM v0 运行起来有点慢 (CPU overhead)

  • vLLM v0 的代码可读性和可二次开发的能力较差

    • 比如v0的Scheduler代码有2k行,改进后的v1代码只有800行
    • 代码改动牵一发而动全身
  • 如何推进代码重构?

    • YM: 在稳定之后完成切换
    • 开发完成后切换的问题:不切实际,新功能 & 新模型的不断涌现
    • vLLM 最重要的特性: 对新模型的支持!!!
      • 易用
      • 性能
      • day0 support(在新模型刚发布就适配) –> tech debt(技术债,
        由于着急为新功能提供支持而导致工程上的不优雅,可能会影响后续新功能的支持)
  • vLLM重构代码的几个阶段

    • Stage 1: v1 的开发
    • Stage 2: v0 & v1 共存
    • Stage 3: 默认开启 v1 (现在)
    • Stage 4: v1 比 v0 具有更多可支持的功能
    • Stage 5: 移除 v0 的代码
  • 为什么Pytorch赢了Tensorflow? 这也是vLLM需要重构的原因

    • Tensorflow曾经说过:我们有更多的功能,更好的性能和更多的硬件支持
    • 原因:研究员更喜欢pytorch,然后他们毕业了…
    • vLLM v0 对研究员们不够友好

📌 2. Scheduler

代码:vllm/v1/core/sched/scheduler.py

  • 调度:统一不同方法下调度tokens的逻辑
    • 比如一个长度为500 tokens的请求
      • Prefill: {r: 500}
      • Decode: {r: 1}
      • Chunk prefill: 256, {r: 256}, {r: 244}
      • Prefix caching: r 命中了200个前缀token: {r: 300}
    • Speculative decoding: 每个请求5个token {r: 5}
    • Multi-modality: r: 100个文本tokens, 500个图像tokens, 100个文本tokens:
      • {r: 100}, {r: 500}, {r: 100}
  • 简化调度逻辑,默认使用chunk prefill,不严格区分prefill和decode
  • 同步调度

🔔 3. General architecture

  • 前后端解耦,Scheduler, API Server, (de) tokenizer分在不同的进程上
  • Scheduler & Worker 在不同的进程中
    • Scheduler, Rank 0 worker在同一个process中并存(在之前的v0版本上)

要获取最新的vLLM更新的干货,可以查看github仓库里meetup的slices

⚡ 3. Worker

  • Persistent batching
    • 对于从CPU到GPU之间的数据传输,我们只需要传上一个batch的tensor增量即可
    • 这个技术不新
    • 相关代码位于: vllm/v1/worker/gpu_input_batch.py, vllm/v1/worker/gpu_worker.py
  • Piecewise cudagraph
    • Cudagraph
      • 记录了一系列CUDA kernel operation然后在之后重放
      • CPU 启动 CUDA kernel 是很慢的, 但是运行一个CUDA kernel是非常快的
      • CUDAGraph: 对于一系列的CUDA kernel, CPU只需要启动一次
        • 不会记录CPU operation, 丧失了灵活性
    • CUDAGraph的缺点: 丧失了灵活性
    • Observation: 灵活性需求通常发生在attention layer而不在MLP layer
    • 解决方法:piece-wise cudagraph, 只在MLP层记录cuda graph,attention的部分使用pytorch eager mode

💡 4. Attention kernel

  • 简化了设置
    • Key observation: 对于每个attention kernel, 最基本的信息来源于大概6-7个tensors
  • Cascade inference (级联推理)
    • 假设有这样的一个场景
      • System prompt: 10,000 tokens
      • 10 user chat, each chat 100 tokens
    • 常规的attention需要读取的内存大小
      • (10,000 + 100) * 10 tokens
    • Cascade inference
      • 10,000 + 100 * 10 tokens
    • vLLM: 使用performance model去决定什么时候使用cascade inference
      • vllm/v1/attention/backends/flash_attn.py: use_cascade attention

🔎 6. Multi-model

  • Embedding as the KV cache reference
  • KV cache 管理(incoming)
    • Hybrid memory allocator…
  • 这部分内容太多,值得开个专题来讲讲,下次见!