2026. 6. 4. 18:31ㆍ분산 ML
What is IBGDA?
GPU Node 간 통신할 때, GPU가 CPU를 시켜서 네트워크 통신하는 게 아니라,
GPU가 직접 NIC(InfiniBand 카드)한테 일을 시키는 기술.
예전 구조: `GPU → CPU Proxy Thread → InfiniBand NIC → 목적지 GPU`

GPU가 다른 노드의 GPU로 데이터를 보내고 싶을 때, GPU가 CPU한테 먼저 요청을 해서, CPU가 NIC(Netword Interface Card)에게 전달, 그러면 NIC이 데이터를 전송하는 순서였다.
통신 library NVSHMEM과 InfiniBand용 NIC (e.g., ConnectX-6 HCA)가 지원되는 환경 가정,
좀 더 자세한 기존 순서 설명:
- application이 GPU memory에 data 생성하는 CUDA kernel launch. (Fig 1. ①)
- application이 통신을 위해 NVSHMEM 연산 (e.g., `nvshmem_put`)을 호출.
- NVSHMEM 연산이 host memory (RAM)에 있는 proxy buffer로 work descriptor를 write. (②)
- NVSHMEM proxy thread가 work descriptor 감지하고 network 연산 개시. (③)
- proxy thread가 work descriptor를 만들고 host memory에 있는 work queue (WQ) 버퍼에 enqueue. (④)
- work descriptor: RDMA write 같은 요청한 연산들, source/dest 주소, 데이터 크기 등등 network 관련 정보 명시.
- CPU가 host mem에 있는 doorbell record (DBR) 버퍼를 update. (⑤)
- DBR buffer: NIC이 doorbell (DB)에 write하는 걸 drop하는 불상사를 대처하기 위한 recovery path 때 사용.
- CPU가 NIC의 DB 레지스터에 write하면 (doorbell "띵동~"), NIC에서 읽음 ("예 누구세요"). (⑥)
- 그러면 NIC이 WQ buffer에서 work descriptor를 읽고 (⑦)
- GPUDirect RDMA를 통해 GPU mem에 있는 data를 copy해서 (⑧)
- 목적지 node로 data를 전송한다. (⑨)
- 전송 완료했다는걸 CPU한테 알리기 위해서, NIC이 host memory의 completion queue (CQ) buffer에 event를 write. (⑩)
- CPU는 그러면 CQ buffer에서 polling 해가지고 NIC이 전송 완료했음을 감지, 그리고 GPU한테 그걸 알림. (GPU mem에 바로 notification flag를 쓰기도 하고 proxy buffer 통해서 알리기도 함.)
-) CPU가 bottleneck이 된다. 요즘 H100 같은 GPU는 엄청난 속도로 연산한다. 게다가 MoE 연산 같은 경우 연산량 자체는 적은 반면 전송량이 작게 많다 (작은 데이터 패킷을 많이!! 발생시킨다). 그러면 CPU proxy thread는 그 많은 요청을 매번 하나하나 처리한다.
최신 NIC는 초당 수억 건의 통신 요청을 처리할 수 있고, GPU 역시 이 정도 속도로 요청을 생성할 수 있다. 반면, CPU 프록시의 처리 속도는 그보다 수 자릿수(orders of magnitude, $10^N$ 배) 낮기 때문에 세밀한(fine-grain) 통신 패턴에서 병목이 발생한다.
GPU : 야 빨리 보내
CPU : 잠깐만...
CPU : 이것도 처리해야 하고...
CPU : 이것도...
CPU : 이것도...
"아니 CPU 거쳐가려니까 너무 느린데, GPU가 직접 NIC를 건드리면 안 되나?"
그 결과가 GPUDirect Async다. 그리고 이를 InfiniBand에 적용한 것이 IBGDA다.
이제 CPU를 거치지 않고 바로: ` GPU → InfiniBand NIC → 목적지 GPU` 이렇게 데이터가 바로 전송된다.

자세히 말하면, GPU가 직접
- Work Queue 작성
- Doorbell 업데이트
- RDMA 요청 생성
을 수행한다.
더 자세히 말하면 (Fig 2 참고):
① 애플리케이션이 CUDA 커널을 실행하고, 이 커널이 GPU 메모리에 데이터를 생성한다.
② 애플리케이션이 통신하기 위해 NVSHMEM 연산(예: nvshmem_put)을 호출한다.
② NVSHMEM 연산은 GPU의 SM을 사용하여 NIC용 Work Descriptor를 생성한 뒤 이를 Work Queue(WQ) 버퍼에 직접 기록한다. CPU Proxy 방식과 달리, 이 WQ 버퍼는 CPU 메모리가 아닌 GPU 메모리에 위치한다.
③ SM은 GPU 메모리에 위치한 Doorbell Record(DBR) 버퍼를 업데이트한다.
④ 이어서 SM은 NIC의 Doorbell(DB) 레지스터에 값을 기록하여 NIC에 새로운 작업이 등록되었음을 알린다.
⑤ NIC는 GPUDirect RDMA를 사용하여 GPU 메모리에 있는 WQ 버퍼로부터 Work Descriptor를 읽어온다.
⑥ NIC는 GPUDirect RDMA를 사용하여 GPU 메모리에 저장된 실제 데이터도 직접 읽어온다.
⑦ NIC는 해당 데이터를 목적지 노드로 전송한다.
⑧ 네트워크 작업이 완료되면 NIC는 GPUDirect RDMA를 사용하여 Completion Queue(CQ) 버퍼에 완료 정보를 기록함으로써 GPU에 작업 완료를 알린다.
=> 이로써 CPU 도움 없이 깔끔하게 전송!!
NVIDIA가 공개한 자료에서는 작은 메시지 전송 시, 최대 약 9.5배 높은 처리량(throughput)과 더 낮고 안정적인 지연시간(latency)을 보여준다. 특히 1KB 이하의 작은 메시지에서 효과가 크다.
'분산 ML' 카테고리의 다른 글
| Context Parallelism v.s. Sequence Parallelism (Megatron-LM 기준) (0) | 2026.05.27 |
|---|---|
| Deep EP (0) | 2026.04.24 |
| Distributed Optimizer ↔ FSDP 차이 (Megatron 코드 기준) (0) | 2026.04.15 |
| CUDA Multicast (0) | 2026.04.13 |
| DISTMM: Accelerating Distributed Multimodal Model Training (0) | 2026.03.18 |