- Published on
PyTorch 2.13 的 torchcomms — 冲着替换 c10d 而来的新分布式通信后端
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 引言 — 每两个月出一版的 PyTorch,以及 2.13
- c10d ProcessGroup — 问题出在哪儿
- torchcomms 是什么
- NCCLX 与 CTran — 一起公开的那些东西
- 2.13 里实际进来了什么
- 诚实的权衡 — 现在还不是该换过去的东西
- 那么今天该做什么
- 结语
- 参考资料
引言 — 每两个月出一版的 PyTorch,以及 2.13
PyTorch 2.13.0 已于 2026 年 7 月 8 日发布。按 GitHub 的发布记录,今年的 PyTorch 出了 2.10(1 月 21 日)、2.11(3 月 23 日)、2.12(5 月 13 日)、2.13(7 月 8 日) — 大致是两个月的间隔。据官方发布博客,2.13 由 2.12 之后 526 位贡献者提交的 3,328 个 commit 构成。
光看亮点清单就知道这个版本相当大。FlexAttention 上了 Apple Silicon(MPS)(在稀疏模式下相对 SDPA 最高约 12 倍 — 官方发布的数值),Inductor 新增了与 Triton 并列的 CuTeDSL 代码生成路径,还进来了号称能把大词表语言模型训练的峰值内存最多降低 4 倍的 nn.LinearCrossEntropyLoss。GPU 内核生成层日趋多样的这股流向,和昨天聊的 Triton Gluon 的故事是同一个脉络。
不过本文想聚焦的,是其中最不花哨的那一项 — torchcomms。用发布说明的话讲,它是「为 PyTorch Distributed 而生的新通信后端,改善大规模集群训练的容错性、扩展性与可调试性」的东西。它不是一个单独的功能,而是分布式层的地基开始被替换的信号,所以就算眼下不用,方向也值得知道。
c10d ProcessGroup — 问题出在哪儿
用过 torch.distributed 的人都熟悉这一层。用 init_process_group() 造出全局状态,调用 dist.all_reduce() 这类全局函数,底下则是 c10d 的 ProcessGroup 抽象包着 NCCL(或 Gloo)的结构。DDP、FSDP、乃至流水线并行,全都立在它上面。
问题在于这层抽象被设计出来的那个时点,和如今的诉求之间的落差。2.13 发布博客是这么总结的 — ProcessGroup 当初就是围着 NCCL 设计的,而随着多维并行、弹性(elastic)扩缩、异构互连让分布式训练变得复杂,现有后端在错误处理与观测性上的局限成了运维团队的瓶颈。torchcomms 的发布文则更直白。现有的 c10d API 背着「相当可观的技术债(significant technical debt)」,难以扩展、也难以现代化,并明确指出 lazy initialization、以及 P2P 运算受限的并发语义这类既有做法,制约了 NCCL 一类库的扩展性。
归纳起来是三点。基于全局状态的 API,导致很难把通信层单独拎出来做实验;以 NCCL 为中心的设计,导致其他厂商与异构硬件成了二等公民;以及到了数万 GPU 的规模,初始化、故障处理、调试都开始力不从心。
torchcomms 是什么
torchcomms 是 2025 年 10 月 22 日在 PyTorch 博客上发布的、设计上与 PyTorch Distributed 配合使用的实验性轻量通信 API。仓库是 meta-pytorch/torchcomms,采用 BSD-3 许可证。发布文列出的目标有六个。
- 通信原语的快速原型开发 — 把通信从 PyTorch 内核的数值原语中剥离出来,在不破坏现有功能的前提下独立实验新的 collective、API 与后端。把 out-of-tree 后端作为一等公民支持。
- 扩展到 10 万 GPU 以上 — 用 eager initialization 取代 lazy init(后端资源由用户显式管理),并以逐模型的提示来优化通信器、NVLink 缓冲区、RoCE 资源的分配。
- 异构硬件支持 — 从一开始就把「在同一个训练作业里混用多代、多厂商的硬件」作为设计目标。
- 大规模下的容错 — 公开可以撑起 torchft 这类上层库的 fault-tolerant 后端。发布文提到 fault-tolerant HSDP 与 Streaming DiLoCo 作为支持对象的算法。
- 单边(one-sided)通信 — 一等地支持 RDMA 风格的 put/get。目标是强化学习、检查点、异步工作流。
- 以设备为中心的 collective — 让通信元数据与逻辑常驻在 GPU 上,把计算与通信融合(包含 IBGDA 这样的 GPU 直连 RDMA)。
API 的设计,跟 c10d 一对比就懂得快。没有全局的 dist.* 函数,所有运算都是面向对象的。一个 TorchComm 对象对应一个设备、一个通信器,在创建时接收设备并立刻(eagerly)初始化,rank 也不是全局 rank,而是以通信器为准。运算按发起顺序执行,需要并发执行时就用批处理 API。把当前 README 的示例概括一下,大概是这个样子。
import torch
from torchcomms import new_comm, ReduceOp
# 用 torchrun 给的环境变量立刻初始化。通信器绑定到单个设备。
comm = new_comm("ncclx", torch.device("cuda"), name="main_comm")
rank = comm.get_rank() # 不是全局 rank,而是这个通信器的 rank
world_size = comm.get_size()
tensor = torch.full((1024,), float(rank + 1), device="cuda")
# 同步 all-reduce
comm.all_reduce(tensor, ReduceOp.SUM, async_op=False)
# 异步 all-reduce
work = comm.all_reduce(tensor, ReduceOp.SUM, async_op=True)
work.wait()
comm.finalize()
与既有并行化库的接点是 DeviceMesh。torchcomms 可以用自带的 init_device_mesh 造出 DeviceMesh,那个 mesh 能原样交给 FSDP2 的 fully_shard(model, device_mesh=mesh)。发布文表示,他们整合进 torchtitan 以验证与 FSDP2、张量并行的兼容性与一致性(整合代码在 torchtitan 的 experiments 路径下)。如果你好奇 torchtitan 本身,我在 Torch-Titan 分布式训练指南里讲过。
按 README,后端里 NCCL、NCCLX、Gloo 默认启用,AMD 用的 RCCL、RCCLX 和 Intel XPU 用的 XCCL 则通过构建选项打开。要求是 Python 3.10 以上、PyTorch 2.8 以上,稳定通道的 pip 安装则被引导到与 PyTorch 2.11 以上搭配的 download.pytorch.org 索引。
NCCLX 与 CTran — 一起公开的那些东西
这次发布里,和 torchcomms 同等重要的是 NCCLX 的开源。NCCLX 是 Meta 对 NCCL 的扩展,把发布文的自述原样搬过来就是:为「扩展到 10 万 GPU 以上」而开发,「被用于 Llama 3 和 Llama 4 这类 LLM 的大规模训练与推理,如今 Meta 的所有生成式 AI 服务都跑在 NCCLX 之上」。列举出的功能有:可扩展的初始化,zero-copy 及 SM-free 通信,自定义 collective 算法,网络流量负载均衡,单边通信,GPU 常驻的低延迟 collective,故障分析与定位(fault analyzer and localization)。
在它下面还有一层叫 CTran(Custom Transport)的传输栈。它承载 NVLink、IB/RoCE、TCP 传输,是在其上组合出 collective、P2P、RMA 这类通信语义的那一层。NCCLX 与 CTran 都是和 torchcomms 一起公开的。
这里得诚实指出的部分 — 上面的数值与使用履历全都是 Meta 的自述。发布文里没有把 NCCLX 的吞吐、延迟与 NCCL 相比的公开基准数值。「10 万 GPU 以上」不是可复现的测量,而是关于内部运营规模的陈述,在什么工作负载、什么拓扑条件下成立也没有公开。说 Gloo 用新的 lazy init 模式能「扩展到 10 万 worker 以上」的那段,同样是自述。可以认为,目前还没有能拿来做采用判断的独立基准。
2.13 里实际进来了什么
发布是去年 10 月的事,但 2.13 是 torchcomms 开始物理地反映进 PyTorch 主仓库的那个版本。以下是在发布说明里能确认到的条目。
- 分布式 CI 整合 — torchcomms 被加入了 PyTorch 的 distributed CI(#181662)。意思是内核有改动时,torchcomms 的路径会一并被验证。
- 用 c10d 测试来验证后端 — 对 TorchComms 后端跑 c10d 的测试套件,并在这个过程中修掉了非目的地 rank 上
gather的一个 bug(#178533)。发布博客把这次整合描述为「既是现有 c10d 后端的现代替代,又维持 API 兼容性」,并把优雅的超时与部分组恢复、结构化日志与 collective 追踪列为改进点。 - 子组创建路径的整理 — TorchComms 启用时把
new_group路由到split_group,而split_group支持不了的参数不再悄悄回退,而是显式报错(#185416)。多后端进程组的split_group行为也被修正了(#182057)。 - symmetric memory 的解耦 —
NCCLSymmetricMemory对ProcessGroupNCCL的显式依赖被移除,于是 torchcomms 这样的 out-of-tree 后端也能用上 symmetric memory 了(#184260)。 - 编入官方文档 —
torch.distributed的文档里加入了 TorchComms 后端的文档(#182711)。
而我个人认为信号最大的那处改动 — 公开 collective API 的改名。在 2.13 里,all_gather_into_tensor 改名成了 all_gather_single,reduce_scatter_tensor 改名成了 reduce_scatter_single(#186123 等)。发布说明给出的理由很明确 — 为了让公开的 torch.distributed API 对齐 torchcomms 的 TorchCommBackend 所用的命名。旧名字会作为薄封装继续工作,但会发出 FutureWarning。不是 torchcomms 在向 c10d 对齐,而是 c10d 在朝 torchcomms 挪动 — 方向很难比这更清楚了。
同一个版本里,FSDP2 拿到了给 reduce-scatter 配专用 NCCL 通信器的可选加入式 API(set_separate_reduce_scatter_group,#186335),从而能与 all-gather 做通信重叠 — 这件事同样落在把通信层切得更灵活的那股流向上。
诚实的权衡 — 现在还不是该换过去的东西
该踩刹车了。
API 不稳定。 发布博客的 torchcomms 条目上挂着 API Unstable 的标记,发布文自己也钉死了一句:「API 尚处早期,在走向成熟的过程中可能经历破坏性变更」。这不是场面话 — 2025 年 10 月发布博客里的示例代码是 comm.allreduce(...),而 2026 年 7 月的当前 README 示例是 comm.all_reduce(...)。意思是,这个阶段早到九个月之间官方示例的方法写法都变了。现在就在这个 API 上垒生产代码,就得做好每个版本都跟着改的心理准备。
对大多数用户来说眼下没有收益。 如果单节点几张卡、或者几十到几百 GPU 上 DDP、FSDP2 跑得好好的,那么就目前而言,torchcomms 没什么能带给你的。eager init 和资源提示想解的那些问题(数万 GPU 的初始化、通信器的资源管理),只在那个规模上才疼。发布文关于过渡的承诺,戳的正是这一点 — c10d 后端接口的废弃会渐进推进、把中断降到最低,并且「大多数用户与模型会像现在这样继续工作」。反过来读就是:对普通用户来说,等着才是官方推荐的路径。
没有独立验证。 如上面指出的,NCCLX 关于规模的主张是 Meta 的自述,没有公开的对比基准。想以性能为依据来采用,依据本身还不存在。
那么现在该谁来看。研究通信原语的人(把新的 collective、后端拿到 out-of-tree 去实验)、有自家通信栈的硬件厂商、大规模跑 torchft 一类容错训练的团队、处理需要单边通信的异步工作负载(RL、检查点)的人 — 大致就是发布文明示的这些对象,而且事实也确实如此。如果你好奇分布式训练栈的整体地形,可以参考分布式训练框架深度解析。
那么今天该做什么
以实务者的标准来梳理就是这样。
- 如果要升到 2.13,先从清理 FutureWarning 开始。
all_gather_into_tensor、reduce_scatter_tensor的调用处会开始发警告。行为不变(薄封装),但新写的代码走all_gather_single、reduce_scatter_single才对。反正最后也会收敛到那个方向。 - 迁移计划先别做。 c10d 之上的 DDP/FSDP2 代码原样放着就行。官方的立场是,这次过渡会以内核团队在底下替换的方式推进。
- 如果你在运营大规模集群,盯着仓库。 meta-pytorch/torchcomms 和 torchtitan 的 experiments 整合是看点,容错、单边通信、以设备为中心的 collective 是路线图的下一步。
结语
torch.distributed 的底层,在整个 2.x 时代实质上一直是同一套结构。torchcomms 是要把那个底层整个换掉的宣言,而 PyTorch 2.13 是这份宣言开始以 CI、测试、文档、公开 API 命名的形态反映进内核仓库的第一个版本。你今天要做的不是迁移,而是认清方向 — 以及把升级途中遇到的那几行 FutureWarning 改掉。地基的更换,就是这样,从几行警告开始的。