当前位置: 首页 > news >正文

GPU 互联架构

GPU 互联架构

版本 产品 带宽(双向/GPU对) 拓扑
NVLink 1.0 P100 160 GB/s 部分互联
NVLink 2.0 V100 300 GB/s 全互联(NVSwitch)
NVLink 3.0 A100 600 GB/s 全互联(NVSwitch)
NVLink 4.0 H100 900 GB/s 全互联(NVSwitch)

NVSwitch 全互联

8 张 GPU + 6 个 NVSwitch 芯片实现全互联:任意两张 GPU 间带宽(A100):直连:600 GB/s经 NVSwitch:600 GB/s(无性能损失)对比 PCIe:PCIe 4.0 x16:64 GB/s(双向)NVLink 3.0:600 GB/s(快 9 倍以上)
# 查看 NVLink 拓扑
nvidia-smi topo -m# 输出示例:
#         GPU0  GPU1  GPU2  GPU3  GPU4  GPU5  GPU6  GPU7
# GPU0     X    NV12  NV12  NV12  NV12  NV12  NV12  NV12
# GPU1    NV12   X    NV12  NV12  NV12  NV12  NV12  NV12
# ...
# NV12 = NVLink 12 条链路连接# 测试 NVLink 带宽
/usr/local/cuda/samples/1_Utilities/p2pBandwidthLatencyTest/p2pBandwidthLatencyTest

节点间互联(InfiniBand)

InfiniBand 技术规格

规格 带宽 延迟 典型产品
EDR(100Gbps) 12.5 GB/s ~600ns Mellanox ConnectX-5
HDR(200Gbps) 25 GB/s ~600ns Mellanox ConnectX-6
NDR(400Gbps) 50 GB/s ~500ns Mellanox ConnectX-7
XDR(800Gbps) 100 GB/s ~500ns 下一代(规划中)

RDMA 通信原理

传统 TCP/IP 通信:应用 → 系统调用 → 内核协议栈 → 网卡驱动 → 网卡延迟:~10-100μs,CPU 参与全程RDMA 通信:应用 → 直接操作网卡(绕过内核)→ 网卡延迟:~600ns,CPU 几乎不参与RDMA 三种实现:InfiniBand:原生 RDMA,性能最好RoCE v2:以太网上的 RDMA,需无损网络iWARP:TCP 上的 RDMA,性能较差

InfiniBand 集群配置

# 安装 MLNX_OFED 驱动
./mlnxofedinstall --all --force# 验证 IB 网卡状态
ibstat
# 关注:State: Active,Physical state: LinkUp# 查看 IB 网络拓扑
ibnetdiscover | head -50# 测试 IB 带宽
# 服务端
ib_write_bw -d mlx5_0 -i 1# 客户端
ib_write_bw -d mlx5_0 -i 1 <server-ip># 测试 IB 延迟
ib_write_lat -d mlx5_0 -i 1 <server-ip>

分布式训练通信

NCCL(NVIDIA Collective Communications Library)

NCCL 是 GPU 集群分布式训练的核心通信库:

# PyTorch 分布式训练示例
import torch
import torch.distributed as dist
import torch.nn as nn
from torch.nn.parallel import DistributedDataParallel as DDPdef setup(rank, world_size):"""初始化分布式环境"""dist.init_process_group(backend='nccl',          # 使用 NCCL 后端init_method='env://',    # 通过环境变量初始化world_size=world_size,rank=rank)def train(rank, world_size):setup(rank, world_size)# 将模型移到对应 GPUdevice = torch.device(f'cuda:{rank}')model = MyModel().to(device)# 包装为 DDP 模型model = DDP(model, device_ids=[rank])optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)for epoch in range(num_epochs):for batch in dataloader:inputs, labels = batchinputs, labels = inputs.to(device), labels.to(device)optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, labels)loss.backward()    # 自动 AllReduce 梯度optimizer.step()dist.destroy_process_group()# 启动(每台机器上运行)
# torchrun --nproc_per_node=8 --nnodes=8 \
#   --node_rank=0 --master_addr=node0 --master_port=29500 \
#   train.py

NCCL 集合通信操作

import torch
import torch.distributed as dist# AllReduce:所有节点的梯度求和,结果广播到所有节点
# 用于数据并行训练的梯度同步
tensor = torch.ones(1024).cuda()
dist.all_reduce(tensor, op=dist.ReduceOp.SUM)# AllGather:收集所有节点的数据
output = [torch.zeros(1024).cuda() for _ in range(world_size)]
dist.all_gather(output, tensor)# Broadcast:将 rank 0 的数据广播到所有节点
dist.broadcast(tensor, src=0)# Scatter:将数据分发到各节点
if rank == 0:scatter_list = [torch.ones(256).cuda() * i for i in range(world_size)]
else:scatter_list = None
output = torch.zeros(256).cuda()
dist.scatter(output, scatter_list, src=0)

NCCL 性能调优

# 设置 NCCL 环境变量
export NCCL_DEBUG=INFO              # 开启调试日志
export NCCL_IB_DISABLE=0           # 启用 InfiniBand
export NCCL_IB_HCA=mlx5_0,mlx5_1  # 指定 IB 网卡
export NCCL_SOCKET_IFNAME=eth0     # 指定以太网接口
export NCCL_TREE_THRESHOLD=0       # 强制使用 Ring AllReduce# 测试 NCCL 性能
git clone https://github.com/NVIDIA/nccl-tests
cd nccl-tests && make MPI=1 MPI_HOME=/usr/local/mpi CUDA_HOME=/usr/local/cuda# 运行 AllReduce 测试
mpirun -np 16 -H node0:8,node1:8 \./build/all_reduce_perf -b 8 -e 8G -f 2 -g 1

网络性能基准

典型 8 节点(64 GPU)集群 AllReduce 带宽:消息大小    InfiniBand HDR    RoCE 100GbE
1MB         ~18 GB/s          ~8 GB/s
100MB        ~22 GB/s         ~11 GB/s
1GB          ~23 GB/s         ~12 GB/s训练吞吐影响:通信效率 = 计算时间 / (计算时间 + 通信时间)目标:通信效率 > 90%(通信不成为瓶颈)