让张量翱翔:R-Fork 加速大模型权重加载

本文介绍 Tensor R-Fork(Tensor Remote Fork),一种创新的权重加载方法,利用高效的跨节点设备间互连,从运行中的 SGLang 实例零拷贝加载张量至新实例。该技术带来三大优势:显著加速权重加载(如 Deepseek-R1 从数分钟缩短至秒级)、消除本地磁盘/DRAM 冗余存储(节省约 600GB)、不干扰推理服务。核心设计基于 GPU-Direct RDMA 构建 P2P 权重存储架构,支持 NCCL 和 TransferEngine 两种后端。性能测试显示,在 8 张 NVIDIA H20 GPU 上加载 Deepseek-R1 模型时间大幅缩短,已实现生产就绪。

TL;DR

我们推出Tensor R-Fork(Tensor Remote Fork),一种新型权重加载方法,利用高效跨节点设备间互连,实现从运行中 SGLang 实例零拷贝加载张量至新实例。

该方法具备三大关键优势:

  • 显著提升权重加载性能;
  • 消除本地磁盘/DRAM 的冗余模型权重存储;
  • 确保推理服务不被干扰。

以 Deepseek-R1 模型为例,加载时间从数分钟缩短至仅数秒,本地磁盘/DRAM 存储节省约 600GB,同时推理服务质量保持稳定。

背景

随着 LLM 服务规模和模型权重尺寸持续扩大,SGLang 实例的冷启动时间已成为生产效率的关键瓶颈。其中,权重加载是最耗时的阶段。

以 Deepseek-R1 为例,从本地磁盘加载需数分钟,从远程存储甚至达数十分钟。随着模型尺寸指数级增长,初始化和数据传输时间将进一步恶化。

如何优化权重加载?最直接方式是最大化权重数据流的瓶颈带宽。行业常见模型加载方式及其瓶颈如下表所示:

加载来源数据流瓶颈
远程存储中心远程存储 → 远程 Ethernet NIC → Ethernet → 本地 Ethernet NIC → 本地 DRAM → 本地 GPU 内存NVMe / Ethernet NIC
本地磁盘磁盘 → DRAM → GPU 内存NVMe
本地 DRAMDRAM → GPU 内存PCIe

能否利用更高带宽的数据流传输张量?答案是YES——跨节点设备间互连可提供数百 GB/s 吞吐量。但关键问题是:如何在 SGLang 中充分利用此互连带宽进行高效权重加载?

为此,我们开发了新型权重加载框架Tensor R-Fork,将 Deepseek-R1 加载时间缩短至数秒,已实现生产就绪。

设计

Tensor R-Fork的核心理念是利用 GPU-Direct RDMA 构建点对点(P2P)权重存储架构

传统数据传输性能低下,因为路径中总存在带宽远低于设备间互连的瓶颈。从数据流分析可知,权重张量存储于各 GPU,可通过 GPU-Direct RDMA 直接跨节点传输。

为最大化 RDMA NIC 带宽利用,我们设计了每 GPU 对的数据传输策略:本地 GPU 直接向/从配对远程 GPU 传输数据。此设计绕过 GPU 与 CPU 间的 PCIe 瓶颈,实现无 CPU/主机内存依赖的高吞吐通信。

从远程 SGLang 实例加载权重的流程如下:

Tensor R-Fork 设计数据流图

实现

为使每个运行实例充当相同模型新实例的权重源,同时最小化(或消除)对运行实例推理服务的干扰,我们实现了两种后端:NCCL 和 TransferEngine。以运行实例 A(源实例)和新实例 B(目标实例)为例,详述权重传输机制。

NCCL 后端

使用NCCL作为后端[1],过程分两阶段:

  1. 源与目标实例间建立通信组。
  2. 通过通信组传输权重。

目标实例初始化时,向指定源实例发送 HTTP 请求启动通信组创建。每个目标 TPWorker 与对应源 TPWorker 建立 NCCL 通信组(源 rank 0 与目标 rank 0 配对等),每组仅两成员。

通信组建立后,各源 TPWorker 通过 NCCL broadcast 将 GPU 内存权重张量广播,目标 TPWorker 直接接收至其 GPU 内存,无中间拷贝。

NCCL 虽利用 GPU-Direct RDMA,但有关键局限:传输干扰源实例推理服务,因:

  1. 通信组建立:源实例需主动参与。
  2. CUDA 内核干扰:NCCL broadcast 触发 CUDA 内核,竞争 GPU 资源导致生成任务延迟峰值。

TransferEngine 后端

为实现无干扰传输,我们引入TransferEngine后端[2],其基于 RDMA 的轻量传输运行时,与源实例各 TPWorker 并行运行,向远程读取者暴露 GPU 驻留权重张量,无需源端 CUDA 内核。

源 SGLang 实例初始化时:

  1. 各 TPWorker 启动 TransferEngine 实例。
  2. TransferEngine 将权重 GPU 内存地址注册至 RDMA 通道。

目标实例初始化时:

  1. 发送 HTTP 请求获取源 TransferEngine 元数据,包括映射至 GPU 内存地址的 RDMA 密钥。
  2. 利用 RDMA 密钥,直接从源 GPU 内存加载权重,不中断源服务。

欲了解更多 TransferEngine?欢迎查看附录 🚀

NCCL vs. TransferEngine

NCCLTransferEngine
部署复杂度✅ 无额外依赖❌ 需额外库 mooncake
传输设置开销✅ 构建通信组仅数百毫秒➖ 注册内存区需数秒,但可与其他初始化重叠
对 GPU 负载无干扰❌ 传输启动 CUDA 内核✅ 无 CUDA 内核

使用方法

详见R-Fork 文档

使用 NCCL 后端

种子实例:

python -m sglang.launch_server [args]

客户端实例:

python -m sglang.launch_server [args] \
  --load-format remote_instance  \
  --remote-instance-weight-loader-seed-instance-ip [seed_instance_ip] \
  --remote-instance-weight-loader-seed-instance-service-port [seed_instance_service_port] \
  --remote-instance-weight-loader-send-weights-group-ports [send_weights_nccl_group_ports_list]  \
  --remote-instance-weight-loader-backend nccl

使用 TransferEngine 后端

种子实例:

python -m sglang.launch_server [args] \
  --remote-instance-weight-loader-start-seed-via-transfer-engine

客户端实例:

python -m sglang.launch_server [args] \
  --load-format remote_instance  \
  --remote-instance-weight-loader-seed-instance-ip [seed_instance_ip] \
  --remote-instance-weight-loader-seed-instance-service-port [seed_instance_service_port] \
  --remote-instance-weight-loader-backend transfer_engine

性能

我们在配备 8 张 NVIDIA H20 GPU 的新 SGLang 实例上测试,从不同来源加载 DeepSeek-R1 模型的性能。

性能对比图

内存区注册可与其他初始化阶段重叠,进一步优化总启动时间。

工业实践

前文手动配置种子实例适用于测试,但工业部署中识别可用种子实例需大量运维开销。

为解决此挑战,我们提出Ten方案(原文截取至此)。