Rust in Everything

一个请求的一生

主线位置:整条「一个请求的一生」。这一部分把 HTTP 进来、模板与分词、调度、前向与采样、反分词、流式返回串成一条线,标出每一段在哪个进程、由什么语言实现;调度和 KV 的内部只点到为止,留给 02、03。
版本:vLLM v0.32.0、SGLang v0.5.22

两个引擎都把「CPU 上的文本处理」和「GPU 上的调度与前向」拆进不同的进程,用 ZMQ 连起来。拆法不同:

vLLM v0.32.0(单卡默认)SGLang v0.5.22(单卡默认)
进程2 个:API server、EngineCore3 个:主进程、Scheduler、DetokenizerManager
HTTP、模板、分词API server(Python)主进程(Python)
调度、前向、采样EngineCore(Python 调 CUDA)Scheduler(Python 调 CUDA)
反分词API server(Python)DetokenizerManager(Python)
通道一对 ZMQ:ROUTER↔DEALER 进,PUSH→PULL 出三段 ZMQ PUSH→PULL 首尾相接成环
序列化msgpack(msgspec)默认 pickle,可切 msgpack
换成 RustVLLM_USE_RUST_FRONTEND=1:整个 API server 换成独立的 Rust 进程,EngineCore 不变SGLANG_RUST_SERVER=1:HTTP、分词、反分词变成 Rust 线程,嵌进调度器进程
  1. vLLM:API server 与 EngineCore:默认路径两个进程上的每一步和源文件;分词放在线程池里,反分词在 API server 的事件循环里做;EngineCore 用两个 IO 线程把 ZMQ 收发和 GPU 步重叠;打开 Rust 前端后,Python 主进程退成看守,HTTP 到反分词整段由 vllm-rs 接手。
  2. SGLang:TokenizerManager、Scheduler、DetokenizerManager:默认路径三个进程首尾相接;聊天模板和分词在主进程的事件循环里同步做;调度器默认走重叠循环;反分词单独一个进程,按批解码;打开 Rust 服务后,主进程只剩等待,调度器进程里多出一组 Rust 线程,进出都走进程内的 flume 通道。

两种 Rust 集成方式的对比、各自覆盖哪些接口,在 两种 Rust 前端。

flowchart TB
  subgraph V["vLLM 默认"]
    va["API server<br/>Python"] -->|"ZMQ ROUTER→DEALER<br/>msgpack"| ve["EngineCore<br/>Python + CUDA"]
    ve -->|"ZMQ PUSH→PULL<br/>msgpack"| va
  end
  subgraph S["SGLang 默认"]
    sm["主进程<br/>HTTP + TokenizerManager<br/>Python"] -->|"ZMQ PUSH→PULL"| ss["Scheduler<br/>Python + CUDA"]
    ss -->|"ZMQ PUSH→PULL"| sd["DetokenizerManager<br/>Python"]
    sd -->|"ZMQ PUSH→PULL"| sm
  end

💬 关联讨论

发起讨论
加载中...