Rust in Everything

Rust 在哪里

版本:vLLM v0.32.0、SGLang v0.5.22;对照 vllm-project/router v0.1.16、mistral.rs v0.9.5

结论先说:两个引擎的 GPU 前向都不碰 Rust。Rust 占的是 CPU 一侧的边:HTTP 和 gRPC 协议、聊天模板与分词、增量反分词、工具调用解析、多副本路由;SGLang 里还有调度器内部的前缀树。

一张总表

组件做什么默认还是可选和 Python 怎么连
vLLM rust/(二进制 vllm-rs)整个 API 服务进程:HTTP / gRPC、聊天模板、分词、多模态预处理、增量反分词、工具和推理解析可选:VLLM_USE_RUST_FRONTEND=1,默认 0(envs.py);只有 completions / chat,api_server_count 固定为 1独立子进程,沿用原来的 ZMQ(ROUTER/PULL 对 DEALER/PUSH)+ msgpack 边界
SGLang sglang-radix-treeUnifiedRadixCache 的树核心:匹配、插入、锁、驱逐、KV 事件默认:SGLANG_UNIFIED_RADIX_TREE_CORE_BACKEND 默认 "rust"(environ.py);非 Linux、torch 不在 2.11–2.14 等情况回退 PythonPyO3 扩展,在调度器进程里
SGLang sglang-serverHTTP、分词、反分词、gRPC、PD bootstrap 注册表可选:SGLANG_RUST_SERVER=1,默认 False(environ.py)线程嵌在 rank-0 调度器进程里,flume 通道传 msgpack 头加命名缓冲区
SGLang sglang-grpc原生 gRPC 入口可选:设 --grpc-port 或 SGLANG_GRPC_PORT 才启动(serving.py)PyO3,进程内
SGLang sglang-mm图像下载、解码、缩放、切块、归一化DeepSeek-V4.1 与 Inkling 在 auto 后端下默认用,加载失败回退 PIL(deepseek_v41.py)PyO3
SGLang router → SMG(sgl-model-gateway)多副本与 PD 路由;cache_aware 策略用按字符的近似前缀树(cache_aware.rs)独立 wheel 和镜像,不是 sglang 的依赖HTTP,或 gRPC
SGLang experimental/sgl-routerKV 感知路由:订阅引擎 KV 事件,按 token 块建索引实验,夜间镜像ZMQ SUB + msgpack
vllm-project/routerSMG 的分支;gRPC 后端复用 vLLM 的 vllm-chat / vllm-tokenizer / vllm-text(Cargo.toml)独立包HTTP,或对 vllm-rs 的 vllm.Inference gRPC
mistral.rs纯 Rust 引擎,基于 candle,自己做分页注意力和调度—对照:这里 Rust 跑前向

两种集成方式

flowchart LR
  subgraph V["vLLM:独立进程"]
    vr["vllm-rs 进程<br/>HTTP 分词 反分词"] -->|"ZMQ + msgpack"| ve["EngineCore 进程<br/>Python 调度 + GPU"]
  end
  subgraph S["SGLang:进程内 PyO3"]
    subgraph sp["rank-0 调度器进程"]
      st["Rust 线程<br/>HTTP 分词 反分词"] -->|"flume 通道"| sc["Python 调度循环"]
      sc --> tree["Rust 前缀树<br/>PyO3 调用"]
    end
  end
  • vLLM 走独立进程。 Python 先绑好 socket,再拉起 vllm-rs 子进程,把文件描述符传过去;之后两边只通过原有的 ZMQ 边界说话。中间试过 PyO3:一个工具解析器桥在 v0.24.0 加入、v0.32.0 前删除,现在只剩 tools/build_rust.py 里一段注释掉的示例。
  • SGLang 走进程内。 前缀树是调度器每一步都要调的 PyO3 对象;可选的 Rust 服务器甚至不另起进程,而是作为线程跑在 rank-0 调度器进程里,Python 调度循环直接从 Rust 通道里取请求。

两条路的代价不同:独立进程隔离好、Python 一侧几乎不用改,但多一跳序列化;进程内省掉 IPC,但 Rust 侧的 panic 和锁会直接落在调度器进程里。两页分别讲清。

本部分各页

  1. 两种前端:vLLM vllm-rs 怎么被 Python 拉起、传哪些 fd,ZMQ 套接字怎么配对,msgpack 兼容性怎么测,覆盖哪些端点、缺哪些,api_server_count 为什么只能是 1,被删掉的 PyO3 解析器桥;SGLang sglang-server 作为调度器进程里的线程,flume 通道,接管了什么、哪些选项不能一起用,依赖 NVIDIA Dynamo 的 crate。
  2. 调度器里的前缀树:SGLang sglang-radix-tree 和 Python 编排的分工,PyO3 接口,节点 arena、互斥锁、LRU 链表和驱逐的数据结构,回退矩阵逐条,v0.5.19 加入、v0.5.21 成为默认。
  3. 路由层:SGLang router → SMG → vllm-project/router 的谱系,按字符的近似树与按 KV 事件的 token 块索引,PD 双发。
  4. 共享的文本栈:分词、聊天模板、工具与推理解析器以 crate 形式在几个项目间流动。
  5. 纯 Rust 引擎作对照:mistral.rs / candle 作对照。

这一部分的数字:代码行数来自 tokei(Rust code 行,不含注释和空行,含 tests/、benches/);CPU 上能测的几组已经测了:vLLM 两种前端对假引擎的吞吐和 TTFT、SGLang 两个树核心的单项操作、experimental/sgl-router 的微基准、vLLM 解析器和分词器的微基准,各页写明环境、样本量和局限。真模型下的前端对比、调度步里的树开销、路由效果仍待实测,各页写明在哪一批跑。

💬 关联讨论

发起讨论
加载中...