how i ai
今天蚂蚁 Ling Infra、阿里、SGLang Team 联合发布推文,讲怎么让推理引擎崩了之后秒级重启。
说模型现在动辄一两百 B、上 T,服务进程一崩,光把权重从盘里读回来就要好几分钟。Ling-2.6-1T 那个 FP8 模型,在 8 张 H20 上整段拉起来要 8 分半,其中 495 秒(93.9%)全花在读盘加载权重上。
每个 TP rank 要啃 120GB 的 safetensors,反序列化、切分、再跑一遍后量化。每次重启都原样重算一遍,可这东西算出来的 GPU 张量是确定的啊,凭什么不能缓存下来?
他们给了一个解法叫 Weight Cache Daemon。在 GPU 上常驻一个进程,把已经量化好、切分好的权重一直留在显存里。引擎哪天崩了重启,新进程不用读盘,直接通过 CUDA IPC 把那块显存零拷贝映射进来就完事,不反序列化、不重新量化。
零拷贝是这事儿能秒级的关键。
引擎先在 meta device 上把模型架子搭起来(不占显存),然后把每个参数的指针直接指到 daemon 那边的 GPU 张量上,数据根本不搬。后量化出来的 weight_scale 之类也一并由 daemon 缓存好、直接映射,不重算。
安全方面,一层是配置指纹校验:模型路径、TP/PP/DP/EP 的切分、量化配置哈希、dtype,还有一组环境戳(GPU 算力和 torch 版本)两个跑在不同后处理分支的进程,权重能干净 map 过去但吐出来全是垃圾,把环境打进 fingerprint 就变成干净的 mismatch,直接触发整盘重载。
另一层是量化方法白名单:CUDA IPC 零拷贝只导原始张量,只有当 process_weights_after_loading() 的全部效果都被这份数据覆盖时才安全;per-tensor FP8、Marlin、AWQ/GPTQ 这类会在 Python 侧盖元数据或重排权重的,直接硬报错,绝不静默出错的数值。目前只验证过 unquantized 和 block-wise FP8。
三种跑法:
daemon(引擎自己拉起 daemon,第一次还是慢)、client(连预跑好的 daemon,这才是快速重启那条路)、off(默认无缓存)。有个细节挺稳:daemon 崩了,已经在跑的引擎不受影响,因为 IPC 张量靠 CUDA 引用计数撑着,得 daemon 和引擎都退了显存才释放;daemon 重启后重新加载、重新发 handle 就行。client 模式配置对不上就回退读盘,daemon 模式对不上直接报错(毕竟俩进程共享一块 GPU,回退会 OOM)。
Ling-2.6-1T 权重加载 495 秒 → 0.63 秒,约 785 倍;端到端启动 8.8 分钟 → 0.528 分钟(降 93.9%)。Qwen3-235B FP8 盘加载 306–327 秒 → 不到 1 秒(约 500 倍),Ling-2.6-1T 那边 405–411 秒 → 不到 1 秒(约 780 倍)。同一张卡上多个引擎实例 map 同一组 handle,盘加载和量化每卡只做一次;主备切换不到 1 秒,而且 standby 不独占整组 GPU。
不过 Weight Cache Daemon 只是整个 Fast Engine Recovery Framework 的第一阶段。目标是冷重启 < 10 秒、热备切换 < 1 秒,现在权重加载这关过了,但 CUDA graph 捕获(现在还要 ~35 秒)、DeepGEMM JIT warmup(~23 秒)、分布式初始化这些还没解决,单节点合计还停在 ~390 秒。后续阶段要把这些压到 10 秒以内。