nvl-rsync:用 NVLink 在 GB200/GB300 Tray 之间传输大模型权重

痛点:大模型权重传输耗时

大模型权重几百G甚至上TB,在多台服务器上传输时非常耗时。

  • 传统网络带宽吃不消:千兆/万兆以太网传一个 200 GB 的权重文件,理论就要几个小时;就算上了 IB/RoCE,跨节点拷贝仍然要等。
  • rsync/scp 不懂 GPU:它们走 TCP,CPU 压缩、网卡发包,瓶颈永远在 PCIe 和网卡上,根本用不到机器里那几 TB/s 的 NVLink 带宽。

GB200/GB300 这种 NVL 机柜里,Tray 之间其实有一条 NVLink Fabric,带宽是 IB 的好几倍,但传统工具完全用不上。nvl-rsync 就是来填这个坑的。

它是什么

nvl-rsync 是一个类似 rsync 的文件/目录同步工具,底层走 NCCL + MNNVL,直接在两个 GB200/GB300 Tray 之间通过 NVLink 传数据。一条命令自动 SSH 到远端拉起接收进程,传完清理,体验和 rsync 一样顺手,但跑的是 NVLink 的速度。

关键特性:

  • 一条命令自动传输:自动 SSH 部署脚本、启动远端 receive、传完精确 kill,无需手动双端操作
  • 增量同步:按文件大小 + SHA-256 校验,未变化的文件直接跳过
  • 多目标扇出:一条命令同时传给多个节点,并发互不影响
  • 多 GPU 并行:按 GPU 拆分文件并行发送,吃满多卡带宽
  • --delete 同步删除:行为与 rsync 一致,远端多余文件自动清理
  • Ctrl+C 精确清理:不会在远端留僵尸进程
  • verify 子命令:独立对比两端文件 hash,不需要 NCCL/GPU,随时可跑

怎么用

1. 前置条件

两个 Tray 在同一个 GB200/GB300 NVLink Domain,nvidia-imex 服务已启动,两端都装好 CUDA Runtime 和 NCCL:

# CUDA 13.x
pip install nvidia-nccl-cu13
# CUDA 12.x
pip install nvidia-nccl-cu12

本地需要能 SSH 到远端。脚本通过系统 ssh 客户端连接,支持几种认证方式:

  • 免密 SSH(推荐):提前配好 authorized_keys 或 SSH Agent,无需额外参数。
  • -i / --ssh-identity:指定私钥路径,等价 ssh -i <key>
    python3 nvl-rsync.py /data/models user@10.10.10.12:/data/models -i ~/.ssh/id_ed25519
    
  • --ask-pass(交互式,较安全):启动时输入一次密码,对该命令所有目标生效;密码通过环境变量 SSHPASS 传给 ssh,不会出现在 ps / shell 历史里。需要本机装了 sshpass
    python3 nvl-rsync.py /data/models user@10.10.10.12:/data/models --ask-pass
    
  • --ssh-password(直接传参,不安全):密码明文写在命令行,会被其他进程、ps、shell 历史看到,仅建议临时测试用,生产环境请改用免密或 --ask-pass
    python3 nvl-rsync.py /data/models user@10.10.10.12:/data/models --ssh-password 'p@ssw0rd'
    

其他 SSH 相关参数:--ssh-user(远端用户名,也可 user@host 内联)、--ssh-port(默认 22,支持 host1=2222,host2=2200 按目标覆盖)、--remote-sudo(远端命令加 sudo)、--remote-python(远端解释器,默认 python3)、--remote-ld-library-path(远端 LD_LIBRARY_PATH,SSH 非交互 shell 不会 source ~/.bashrc)。

--ask-pass--ssh-password 都依赖 sshpass,且不能同时使用。

2. 一条命令传一个目录

python3 nvl-rsync.py /data/models user@10.10.10.12:/data/models

rsync 几乎一样的语法。脚本会自动把自身部署到远端 ~/.nvl-rsync/,拉起接收进程,传完清理。

3. 多节点扇出 + 多 GPU 并行 + 同步删除

python3 nvl-rsync.py /data/models \
  user@10.10.10.12:/data/models \
  user@10.10.10.13:/data/models \
  --local-gpu 0,1,2,3 --remote-gpu 0,1,2,3 \
  --delete

一条命令同时分发到两个节点,每端 4 张卡并行,并自动删除远端多余文件。

4. 传完验证一下

python3 nvl-rsync.py verify /data/models user@10.10.10.12:/data/models

verify 走 SSH 在两端算 hash 再对比,不需要 GPU,随时可以单独跑。

5. 不想用 SSH 自动化?手动双端也行

接收端先起:

python3 nvl-rsync.py receive --dst-root /data/out --gpu 0,1,2,3 --port 29500

发送端再连:

python3 nvl-rsync.py send /data/models \
  --peer-addr 10.10.10.12 --port 29500 --gpu 0,1,2,3 --delete

限制:只能在同一个柜子的 Tray 之间用

nvl-rsync 走的是 NVLink Fabric + MNNVL,前提是两端 GPU 在同一个 GB200/GB300 NVLink Domain/Partition 内——也就是同一个机柜(或同一个 NVLink Partition)里的不同 Tray。跨机柜、跨网络、跨数据中心都不行,因为 NVLink 物理上到不了那里,这种场景还是得回到 rsync / IB / 对象存储。

除此之外还有几个使用上的限制:

  • 符号链接会被跳过(记录警告,不传输)
  • 不同步文件权限/属主,只保证内容和目录结构一致
  • 目标目录在并发任务之间重叠时行为未定义,避免多个任务写同一个目录
  • 底层通过 ctypes 直接调 CUDA/NCCL,遇到 NCCL 版本兼容性问题需要检查 ncclGetVersion 并升级 NCCL

小结

大模型时代,权重文件的搬运本身就是工程瓶颈。nvl-rsync 的思路很简单:既然机器里已经有一条几 TB/s 的 NVLink,为什么还要让大文件挤以太网? 把 NCCL 当传输层、把 rsync 的体验包在外面,一条命令就把 Tray 之间的同步从「等几个小时」变成「等几分钟」。