模型越来越大,推理引擎的冷启动就越来越痛。Ling-2.6-1T 这类万亿级模型,重启一次要等 8.8 分钟才能重新接客。LMSYS 联合蚂蚁、阿里的团队正是冲着这个痛点,在 SGLang 里引入了 Weight Cache Daemon(权重缓存守护进程):让权重常驻 GPU 显存,引擎重启时用 CUDA IPC 零拷贝直接映射,把权重加载从分钟级压到亚秒级。

这是 SGLang Fast Engine Recovery Framework(快速恢复框架)的第一阶段,最终目标是对生产推理服务做到 <10 秒冷启动、<1 秒热备切换

核心结果

指标之前之后提升
权重加载(Ling-2.6-1T FP8)~495s~0.63s约 785×
端到端引擎启动8.8 min0.528 min缩短 93.9%
热备故障切换<1s(零拷贝共享权重)近零停机

时间都花哪了?

团队对 Ling-2.6-1T FP8 一次完整启动做了逐阶段画像:权重从磁盘加载独占 93.2% 的时间。每个 TP rank 要从磁盘读约 120GB 的 safetensors,反序列化、做 TP 分片、再跑一遍后量化变换(FP8 量化、权重 repack)。这些工作在每次重启时都一模一样地重复——可结果张量是确定性的,而且往往已经在显存里躺着了。既然如此,何必每次从磁盘重读?

阶段耗时占比说明
加载权重(磁盘 I/O 瓶颈)~495s93.9%161 分片、W8A8 FP8,最慢 rank 495s
Tokenizer 初始化~13s2.4%加载并初始化
Init torch 分布式~5s0.9%NCCL、8 卡 H20、NVLink mesh
其他(CUDA graph、Server ready 等)~14s2.7%
合计~527s100%约 8.8 分钟

设计:持久权重缓存 + CUDA IPC

Weight Cache Daemon 是一个常驻 GPU 进程,把”后量化 + TP 分片后的权重”常驻在显存中。引擎重启时,新进程通过 CUDA IPC 从守护进程零拷贝映射权重——没有磁盘 I/O、没有反序列化、没有重复量化。每张 GPU 上跑一个守护进程,对应自己的 TP rank。

守护进程负责:从磁盘加载权重(磁盘 → TP 分片 → 量化 → repack 的完整流水线)→ 把 state_dict() 里每个参数/缓存导出为 CUDA IPC handle → 记录 CacheConfig 指纹 → 通过 Unix socket 把 IPC handle 提供给请求的引擎进程。引擎连上守护进程后,校验配置兼容性,把参数指针直接指到 IPC 映射的显存张量上,不拷贝任何数据

实现零拷贝的关键是 meta device:引擎先在 meta device 上初始化模型(不分配显存),再用 IPC 映射的张量替换每个参数的 data 指针。后量化产生的参数(如 FP8 量化的 weight_scale)也被守护进程缓存并直接映射,无需重新量化。

安全第一:配置校验 + IPC 允许清单

任何配置不匹配都会触发完整磁盘重载,宁可慢也不出错。校验字段包括:model_path / model_arch / revision(模型对不对)、tp_size/tp_rankpp_size/pp_rankdp_size/ep_sizequant_method + quant_config_hashdtype、以及 device_capability + torch_version 构成的环境戳——后两项把”能干净映射但数值是错的”硬转成明确的不匹配,避免守护进程和客户端走了不同后处理分支时悄悄产出垃圾权重。

此外,量化方法受 IPC 允许清单门控。CUDA IPC 零拷贝只导出原始张量数据,只有当 process_weights_after_loading() 的全部效果都落在这些数据上时才是正确的;像 per-tensor FP8、Marlin、AWQ/GPTQ 这种会在 Python 侧盖章元数据或 repack/转置权重的方法,会直接抛硬错误而不是静默产出错误数值。目前验证通过的是 unquantized 与 block-wise FP8,更多方法在端到端验证后陆续加入。

三种模式

模式流程权重加载显存适用
daemon引擎拉起守护进程 → 从磁盘加载 → 引擎映射 IPC<1s(守护就绪后)1×(共享)首次启动,引擎托管守护进程生命周期
client连接已运行的守护进程 → 映射 IPC<1s1×(共享)引擎重启,守护进程预先运行(快恢复主路径)
off普通从磁盘加载405–411s默认,不缓存

不止重启:解锁的生产场景

  • 多实例权重共享:每 GPU 一个守护进程,多个引擎实例(比如独立的多个服务)零拷贝映射同一批 IPC handle。无论多少个实例消费,每个 GPU 上权重只从磁盘加载和量化一次
  • 优先级共服务:同 GPU 上跑高优先级在线服务 + 低优先级批任务,共享同一守护进程。低优先级实例可在亚秒内被驱逐再重生,无需重载权重,灵活分时。
  • 主动-被动故障切换:主备引擎共享同一守护进程,备机零拷贝映射权重保持热态;主故障时备机 <1 秒接管,无需为闲置副本独占整组 GPU——对比传统热备部署能省下一倍硬件成本。

实测性能

模型权重磁盘加载IPC 零拷贝加速
Qwen3-235B FP8~235 GB~306–327s<1s约 500×
Ling-2.6-1T~1TB~405–411s<1s约 780×

怎么用

单节点一次性拉起所有 TP rank 的守护进程:

python -m sglang.srt.weight_cache.daemon \
  --model-path /path/to/model --tp-size 4 \
  --load-format auto --dtype auto --quantization fp8

# 就绪检查(每个 rank 写一个 .ready 文件):
ls /tmp/sglang_weight_cache_rank*.ready

启动引擎、以 client 模式连接已运行的守护进程(快恢复主路径):

python -m sglang.launch_server \
  --model-path /path/to/model --tp-size 4 \
  --weight-cache-mode client

多节点:每个节点跑自己的守护进程并加入同一个分布式组,--nnodes / --node-rank / --dist-init-method 各节点需一致,$MASTER_ADDR 指向 node 0;守护进程与引擎客户端使用不同的 rendezvous 端口(守护 29500,客户端 29600)。

路线图:不止 Weight Cache

Fast Engine Recovery Framework 目标 <10 秒冷启动、<1 秒热备切换。当前阶段(Phase 1)已覆盖 TP + PP、单/多节点、per-GPU 零拷贝 CUDA IPC、unquantized + block-wise FP8。后续规划还包括:CUDA graph 序列化、DeepGEMM JIT 预热缓存、惰性 tokenizer 初始化、NCCL session 复用、KV cache 恢复(在途上下文跨重启存续),以及扩展到更多量化方法、DP/EP、多模态与 LoRA、RL 在线更新的原地权重刷新、跨机/集群共享等。完整计划公开跟踪在 sgl-project/sglang#33522

小结

  • SGLang 引入 Weight Cache Daemon:让后量化、TP 分片权重常驻显存,重启时 CUDA IPC 零拷贝映射。
  • 权重加载从 ~495s 降到 ~0.63s(约 785×),端到端启动缩短 93.9%。
  • 配置校验 + IPC 允许清单双保险,安全优先、不匹配自动回退磁盘重载。
  • 解锁多实例权重共享、优先级共服务、<1s 热备切换等生产模式。
  • 这是 Fast Engine Recovery Framework 第一阶段,目标是 <10s 冷启动、<1s 热备切换。

来源:LMSYS Org Blog — Fast Engine Recovery: Sub-Second Engine Restart for SGLang via Weight Cache Daemon(蚂蚁 Ling 基础设施团队 + 阿里 + SGLang 团队,2026-08-21)