Skip to content
Published on

PyTorch 2.13의 torchcomms — c10d를 대체하러 온 새 분산 통신 백엔드

공유하기
Authors

들어가며 — 두 달마다 나오는 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개 커밋으로 구성됐습니다.

하이라이트 목록만 봐도 릴리스가 꽤 큽니다. 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 라이선스입니다. 발표문이 밝힌 목표는 여섯 가지입니다.

  1. 통신 프리미티브의 빠른 프로토타이핑 — 통신을 PyTorch 코어의 수치 프리미티브에서 분리해, 기존 기능을 깨지 않고 새 collective·API·백엔드를 독립적으로 실험. out-of-tree 백엔드를 일급으로 지원.
  2. 10만 GPU 이상으로의 스케일링 — lazy init 대신 eager initialization(백엔드 자원을 사용자가 명시적으로 관리)과 모델별 힌트로 커뮤니케이터·NVLink 버퍼·RoCE 자원 할당을 최적화.
  3. 이기종 하드웨어 지원 — 한 학습 잡 안에서 여러 하드웨어 세대·벤더 혼합을 처음부터 설계 목표로.
  4. 대규모 내결함성 — torchft 같은 상위 라이브러리를 받칠 fault-tolerant 백엔드 공개. 발표문은 fault-tolerant HSDP와 Streaming DiLoCo를 지원 대상 알고리즘으로 언급.
  5. 단방향(one-sided) 통신 — RDMA 스타일 put/get을 일급 지원. 강화학습·체크포인팅·비동기 워크플로가 대상.
  6. 디바이스 중심 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 자체가 궁금하다면 torchtitan 분산 학습 가이드에서 다뤘습니다.

백엔드는 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는 NCCL에 대한 Meta의 확장으로, 발표문의 자체 서술을 그대로 옮기면 "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 자체 서술입니다. 발표문에는 NCCL 대비 NCCLX의 처리량·지연을 비교한 공개 벤치마크 수치가 없습니다. "10만 GPU 이상"은 재현 가능한 측정이 아니라 내부 운영 규모에 대한 진술이고, 어떤 워크로드·토폴로지 조건인지도 공개돼 있지 않습니다. Gloo에 새 lazy init 모드로 "10만 워커 이상 스케일" 운운하는 대목도 마찬가지로 자체 서술입니다. 채택 판단에 쓸 독립 벤치마크는 아직 없다고 보는 게 맞습니다.

2.13에서 실제로 들어온 것

발표는 작년 10월이었지만, 2.13은 torchcomms가 PyTorch 본체 저장소에 물리적으로 반영되기 시작한 릴리스입니다. 릴리스 노트에서 확인되는 항목들입니다.

  • 분산 CI 통합 — torchcomms가 PyTorch distributed CI에 추가됐습니다(#181662). 코어가 바뀔 때 torchcomms 경로가 함께 검증된다는 뜻입니다.
  • c10d 테스트로 백엔드 검증 — TorchComms 백엔드에 c10d 테스트 스위트를 돌리고, 그 과정에서 비목적지 rank의 gather 버그를 수정(#178533). 릴리스 블로그는 이 통합을 "기존 c10d 백엔드의 현대적 대안이되 API 호환성 유지"로 설명하며, 개선점으로 우아한 타임아웃과 부분 그룹 복구, 구조화 로깅과 collective 추적을 듭니다.
  • 서브그룹 생성 경로 정리 — TorchComms가 활성일 때 new_groupsplit_group으로 라우팅하고, split_group이 지원 못 하는 인자는 조용히 폴백하는 대신 명시적으로 에러를 냅니다(#185416). 멀티 백엔드 프로세스 그룹의 split_group 동작도 수정됐습니다(#182057).
  • symmetric memory 디커플링NCCLSymmetricMemoryProcessGroupNCCL 명시적 의존이 제거돼, torchcomms 같은 out-of-tree 백엔드에서도 symmetric memory를 쓸 수 있게 됐습니다(#184260).
  • 공식 문서 편입torch.distributed 문서에 TorchComms 백엔드 문서가 추가됐습니다(#182711).

그리고 개인적으로 가장 큰 신호라고 보는 변경 — 공개 collective API의 개명입니다. 2.13에서 all_gather_into_tensorall_gather_single로, reduce_scatter_tensorreduce_scatter_single로 이름이 바뀌었습니다(#186123 외). 릴리스 노트의 이유 설명이 명시적입니다 — torchcomms의 TorchCommBackend가 쓰는 네이밍에 공개 torch.distributed API를 맞추기 위해서. 기존 이름은 얇은 래퍼로 계속 동작하지만 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(...)입니다. 9개월 사이에 공식 예제의 메서드 표기가 달라졌을 정도의 단계라는 뜻입니다. 지금 이 API 위에 프로덕션 코드를 쌓으면 릴리스마다 따라가며 고칠 각오를 해야 합니다.

대부분의 사용자에게 당장의 이득이 없습니다. 단일 노드 몇 장, 혹은 수십~수백 GPU에서 DDP·FSDP2가 잘 돌고 있다면 torchcomms로 얻을 게 현재로선 없습니다. eager init과 자원 힌트가 풀려는 문제(수만 GPU 초기화, 커뮤니케이터 자원 관리)는 그 규모에서만 아픕니다. 발표문의 전환 약속도 정확히 그 지점을 짚습니다 — c10d 백엔드 인터페이스의 폐기는 점진적으로, 최소한의 중단으로 진행되며 "대부분의 사용자와 모델은 지금처럼 계속 동작"할 것이라고. 뒤집어 읽으면, 일반 사용자는 기다리는 게 공식 권장 경로라는 뜻입니다.

독립 검증이 없습니다. 위에서 짚었듯 NCCLX의 스케일 주장은 Meta 자체 서술이고, 공개된 비교 벤치마크가 없습니다. 성능을 근거로 채택하기에는 근거 자체가 아직 없습니다.

그럼 누가 지금 봐야 하나. 통신 프리미티브를 연구하는 사람(새 collective·백엔드를 out-of-tree로 실험), 자체 통신 스택을 가진 하드웨어 벤더, torchft류 내결함성 학습을 대규모로 굴리는 팀, 단방향 통신이 필요한 비동기 워크로드(RL, 체크포인팅)를 다루는 사람 — 이 정도가 발표문이 명시한 대상이고, 실제로 그렇습니다. 분산 학습 스택 전반의 지형이 궁금하다면 분산 학습 프레임워크 딥다이브를 참고하세요.

그래서 오늘 할 일

실무자 기준으로 정리하면 이렇습니다.

  1. 2.13으로 올린다면 FutureWarning부터 정리하세요. all_gather_into_tensor·reduce_scatter_tensor 호출부가 경고를 내기 시작합니다. 동작은 그대로지만(얇은 래퍼), 새로 쓰는 코드는 all_gather_single·reduce_scatter_single로 가는 게 맞습니다. 어차피 그 방향으로 수렴합니다.
  2. 마이그레이션 계획은 아직 세우지 마세요. c10d 위의 DDP/FSDP2 코드는 그대로 두면 됩니다. 전환은 코어 팀이 밑에서 갈아끼우는 방식으로 진행된다는 게 공식 입장입니다.
  3. 대규모 클러스터를 운영한다면 저장소를 주시하세요. meta-pytorch/torchcomms와 torchtitan의 experiments 통합이 관전 포인트이고, 내결함성·단방향 통신·디바이스 중심 collective가 로드맵의 다음 단계입니다.

마치며

torch.distributed의 밑단은 2.x 시대 내내 사실상 같은 구조였습니다. torchcomms는 그 밑단을 통째로 갈아끼우겠다는 선언이고, PyTorch 2.13은 그 선언이 코어 저장소에 CI·테스트·문서·공개 API 네이밍의 형태로 반영되기 시작한 첫 릴리스입니다. 오늘 당신이 할 일은 마이그레이션이 아니라 방향 인지입니다 — 그리고 업그레이드하면서 만나는 FutureWarning 몇 줄을 고치는 것. 기반 교체는 이렇게, 경고 몇 줄에서 시작됩니다.

참고 자료