万亿参数 1.3 秒推权重,跨网卡 RDMA 库避开厂商锁定

fabric-lib: RDMA Point-to-Point Communication for LLM Systems

Nandor Licker, Kevin Hu, Vladimir Zaytsev, Lequn Chen

Perplexity AI

cs.DC

2025-11-01

Perplexity 开源跨网卡通信库 fabric-lib,用无序 WriteImm 统一 ConnectX 与 AWS EFA,峰值 400 Gbps。万亿参数 RL 权重 1.3 秒推到推理卡,MoE 解码在 ConnectX-7 赶上 DeepEP,EFA 上首次达到可用延迟。

这篇在解决什么

LLM 系统现在大量依赖点对点通信。prefill 和 decode 拆到不同机器之后要搬 KvCache;MoE 要把 token 按专家打散再收回来;异步 RL 要把训练侧刚更新的权重推到推理卡。这些模式跟 NCCL 擅长的静态集合通信对不上号。

集合通信要求固定成员、同步建组、缓冲区形状一致。动态扩缩 prefiller 和 decoder 会卡在建组上,稀疏的 MoE 路由会被均匀 buffer 逼成稠密传输。NCCL 也暴露了 Send/Recv,拼不出可用延迟。

HPC 这边 RDMA 的单边 Write 早就能做低延迟大带宽传输。卡住的是网卡不统一。NVIDIA ConnectX 走可靠连接 RC,保序;AWS Elastic Fabric Adapter(EFA)走自研 SRD,可靠但不保序。DeepEP 绑死 GPU 发起的 IBGDA,只有 ConnectX 有;NVSHMEM 在 EFA 上掉得很厉害;Mooncake 和 NIXL 当时要么没有 EFA,要么还是雏形。云上两家网卡没法共用一套通信库。

方法

Perplexity 的切入点很具体:ConnectX 的 RC 可以主动忽略保序,EFA 的 SRD 本来就不保序,两边的公共子集是「可靠但不保序」。fabric-lib 的 TransferEngine 就建在这个子集上。

核心原语是带 32 位立即数的单边 WriteImm,再配一个 ImmCounter。接收端在完成队列里按立即数累加,攒够约定数量再通知上层,不依赖报文到达顺序。正确性靠 PCIe 写序:WriteImm 的数据先于立即数发出,CPU 看到计数达标后再向 GPU 发后续事务,交换机能保证 GPU 已经看到数据。

引擎用 Rust 写,每个 GPU 一个 worker,绑在对应 NUMA 核上。多网卡对应用透明:ConnectX-7 一张卡就是 400 Gbps,AWS p5 要四张 100 Gbps EFA 绑在一起才到同样带宽,p5en 是两张 200 Gbps。传输按网卡分片轮转。EFA 走 libfabric,ConnectX 走 libibverbs,后者把 Send/Recv 和 WriteImm 拆到两条 RC 队列,避免完成队列互相抢。GPU 进度靠 UVM watcher:CUDA Graph 里的 kernel 改一个统一虚拟内存字,CPU 用 GDRCopy 轮询,触发下一层传输。整套是 host proxy,不走 GPU 直发 RDMA。

三个已经上线的用法:

结果

评测两套机器:8×H200、每卡 2×200 Gbps EFA;8×H100、每卡 400 Gbps ConnectX-7。

操作EFAConnectX-7
单次 Write 256 KiB54 Gbps116 Gbps
分页 Write 64 KiB364 Gbps370 Gbps
单次 Write 32 MiB336 Gbps378 Gbps

分页 64 KiB 接近 KvCache 一页,两边都能吃满带宽。单次 Write 要到 16 MiB 才饱和,这也解释了 MoE 那种 256 KiB 报文在 EFA 上吃不满。跟当时的 NIXL v0.6.1 比,TransferEngine 略快。

KvCache 用 Qwen3-235B、H200 TP4,页大小 32 kB(128 token)。16K 序列非分离 TTFT 929 ms,分离后 1042 ms;逐层传输 1.61 ms,同层计算 9.86 ms,传输被算力盖住。TTFT 变慢主要来自推理引擎多跑了一次最后输入 token 的 decode,不是 RDMA。Rust 侧 UvmWatcher 回调 p50 是 6.2 µs。

RL 权重:Kimi-K2 约 1T 参数,256 张训练卡 BF16(FSDP/PP/EP=16/2/8)推到 128 张推理卡 FP8(EP=32)。单 rank 总耗时 1233 ms。关键路径是 fulltensor 反分片 518 ms、等其他 rank 357 ms;RDMA 提交 26 ms(1144 个 WR),流水线盖不住的传输只剩 42 ms。DeepSeek-V3-671B 和 Qwen3-235B 的训练日志在 1.2-2 s。对照现有框架公开的 10-100 s,差一个数量级。引言写「超过 100 倍」,按他们给的对照区间,更接近 8-80 倍。

MoE 端到端(DeepSeek-V3,MTP,EP=DP=64,tokens/s):

集群实现batch=2batch=8batch=32
H200 EFAOurs66.856.532.0
H200 EFApplx-kernels21.011.64.9
H100 CX-7Ours78.467.736.1
H100 CX-7DeepEP73.865.836.3

EFA 上相对 NVSHMEM 那套 pplx-kernels 是 3-6 倍,论文称这是 EFA 上第一套可用延迟。ConnectX-7 上跟 DeepEP 持平或略快,尽管走的是 host proxy 不是 IBGDA。

微基准 decode、EP64:dispatch 本方案 CX-7 190 µs、DeepEP 180 µs;combine 311 µs 对 327 µs。EP16 和 EP32 两边 dispatch、combine 都更快。EP64 dispatch 慢在代理线程给 56 个跨节点 peer 入队,每个大约 1 µs。EFA decode 延迟大约落后 ConnectX 30%。Prefill 上 DeepEP 更强,尤其 combine:发送端先做部分求和,RDMA 字节少很多,累加精度掉到 bf16。

为什么重要

这是一套已经在生产里跑过三种模式的可移植点对点层,不是又一个只在 ConnectX 上刷延迟的 kernel。AWS 上做分离推理、MoE 服务、异步 RL 的团队,以前几乎没有能用的选择。

集合通信该继续用在张量并行、数据并行这种静态模式上。动态成员、稀疏路由、单边推权重,走这套更合适。代码开源在 pplx-garden,API 不绑网卡;后面接 eRDMA、Broadcom 这类 RC 兼容卡,应用层不用改。

它是渐进工程,不是新算法。价值在于把「可靠但不保序」当成一等公民,把多网卡聚合和完成通知做成可复用原语。

局限与存疑

论文讨论写得很清楚:GPU 发起 RDMA 在多数云实例上还没有(AWS p5/p5e、eRDMA),p5en 也只是雏形,host proxy 是迁就现状。下一代宽 NVLink 域(GB200 NVL72)会把 MoE 通信从 RDMA 上挪走,这套对 MoE 的长期价值会缩。KvCache 和 RL 权重的 RDMA 已经被计算盖住,CPU 代理不伤端到端。

Prefill 没有 DeepEP 那套节点内 NVLink 复制和发送端部分求和。decode 向 kernel 也不做分块,接收缓冲按最坏情况预留,能部署的模型范围更窄。所有 peer 必须每 GPU 网卡数相同。Read 和原子操作故意没做,延迟不合适。

端到端跑在自研 PyTorch 推理引擎上,跟 vLLM、SGLang 的 DeepEP 集成不是同一套运行时。NIXL 后来也加了初步 EFA 支持,可移植性优势会随时间变薄。RL「100 倍」那句对照的是 10-100 s 的公开数字,分母跨了一个数量级,不宜当精确倍数引用。

术语

原文与代码

社区讨论

相关论文

全部论文解读