目录

为什么写这篇文章?

测评结论速览

✅ 核心优势

⚠️ 待优化点

文章综述

评测总结

一、CANN仓库与HCCL简介

1.1 什么是CANN?

1.2 什么是HCCL?

1.3 HCCL源码目录结构

1.4 为什么需要HCCL?

二、库亮点

2.1 高性能通信

2.2 丰富的通信原语

2.3 框架无缝集成

2.4 灵活的拓扑配置

三、应用场景

3.1 大模型训练

3.2 分布式推理

3.3 科学计算

四、上手指南

4.1 环境准备

4.2 环境验证

五、代码示例

5.1 分布式训练脚本(完整版)

NotebookA(10.202.73.94)- Rank 0

NotebookB(10.202.73.95)- Rank 1

5.2 运行步骤(完整实操流程)

步骤1:激活Notebook

步骤2:获取Notebook的IP

步骤3:创建Notebook

步骤4:执行初始化

步骤5:同步执行后续操作

步骤6:验证结果

六、最佳实践

6.1 网络优化

6.2 通信优化

6.3 常见问题

6.4 故障排查

参考资料:


为什么写这篇文章?

随着大模型训练需求的爆发式增长,分布式训练已成为AI开发者的必备技能。作为CANN生态中的核心通信组件,HCCL承担着多机多卡训练中数据同步的关键任务。本文基于gitcode平台上的两台NPU Notebook,对HCCL进行了完整的体验、测试与评测,旨在帮助开发者:

  • 了解HCCL的核心能力:它能为分布式训练带来什么价值?
  • 验证实际性能表现:在真实环境中的通信效率如何?
  • 掌握实操部署方法:如何快速搭建HCCL分布式训练环境?
  • 发现优化空间:当前版本有哪些可以改进的地方?

测评结论速览

✅ 核心优势

优势

说明

开箱即用

与PyTorch分布式模块API一致,学习成本极低

高性能通信

HCCS互联带宽高达392GB/s,RDMA支持降低延迟

智能拓扑感知

自动识别硬件拓扑,选择最优通信路径

丰富的通信原语

支持AllReduce、AllGather、Broadcast等完整原语

框架无缝集成

一行代码切换backend='hccl'即可使用

⚠️ 待优化点

问题

说明

文档完善度

部分API文档可以更详细

调试工具

缺少可视化调试工具

错误提示

部分错误信息可以更友好

社区生态

相比NCCL,社区资源相对较少


文章综述

本文将从以下维度全面解析HCCL:

┌─────────────────────────────────────────────────────────────┐
│                    文章内容架构                              │
├─────────────────────────────────────────────────────────────┤
│  1. CANN仓库介绍 → HCCL在生态中的定位                       │
│  2. 核心特性解析 → 高性能通信、丰富原语、框架集成            │
│  3. 应用场景分析 → 大模型训练、分布式推理、科学计算          │
│  4. 实操部署指南 → 两台Notebook完整部署流程                 │
│  5. 性能评测展示 → 通信延迟、吞吐量实测数据                  │
│  6. 最佳实践总结 → 网络优化、通信优化、故障排查              │
└─────────────────────────────────────────────────────────────┘

阅读收获

  • 理解HCCL在CANN生态中的核心价值
  • 掌握多机分布式训练的完整部署流程
  • 获得真实环境下的性能测试数据
  • 学会常见问题的排查与优化方法
评测总结

测试项

结果

说明

AllReduce

✅ 通过

梯度同步正确

Broadcast

✅ 通过

数据广播正确

AllGather

✅ 通过

数据收集正确

DDP训练

✅ 通过

分布式训练正常

综合评测:HCCL在真实NPU环境下表现稳定可靠,AllReduce、Broadcast、AllGather等核心通信原语均工作正常,完全满足分布式训练需求。


一、CANN仓库与HCCL简介

1.1 什么是CANN?

CANN(Compute Architecture for Neural Networks,神经网络计算架构)是面向AI领域的异构计算架构,为AI开发者提供了一套完整的开发工具链。CANN开源仓库托管在gitcode上,包含了深度学习框架所需的核心组件。

CANN社区地址AtomGit - 全球开发者的开源社区,开源代码托管平台

CANN架构采用分层设计,从底层硬件到上层应用框架,提供了完整的AI计算栈:

┌─────────────────────────────────────────────────────┐
│                    应用层                            │
│         PyTorch / TensorFlow / MindSpore            │
├─────────────────────────────────────────────────────┤
│                    框架适配层                        │
│              Torch_npu / TF Adapter                  │
├─────────────────────────────────────────────────────┤
│                    CANN                              │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐            │
│  │   ACL    │ │   HCCL   │ │   ATB    │            │
│  │ (计算库) │ │(通信库)  │ │(加速库)  │            │
│  └──────────┘ └──────────┘ └──────────┘            │
├─────────────────────────────────────────────────────┤
│                    硬件层                            │
│                   NPU设备                            │
└─────────────────────────────────────────────────────┘

CANN核心模块介绍

模块

全称

说明

ACL

Ascend Computing Language

底层计算接口,提供算子调用能力

HCCL

Huawei Collective Communication Library

集合通信库,分布式训练通信组件

ATB

Acceleration Tensor Base

算子加速库,提供高性能算子实现

AOE

Auto Optimization Engine

自动优化引擎,支持算子自动调优

1.2 什么是HCCL?

HCCL(Huawei Collective Communication Library,集合通信库)是CANN仓库中的核心通信组件,为NPU集群提供高性能、高可靠性的通信方案。HCCL向上支持多种AI框架,向下实现多款昇腾AI处理器之间的高效互联,其架构如下图所示。

1.3 HCCL源码目录结构

HCCL在CANN仓库中有完整的源码实现,开发者可以直接查看和学习:

│── src                         # HCCL算子源码目录
|    ├── common                 # 通用逻辑,包括类型定义、日志模块等
|    └── ops                    # HCCL算子实现
|        ├── all_gather         # AllGather算子实现
|        ├── all_gather_v       # AllGatherV算子实现
|        ├── all_reduce         # AllReduce算子实现
|        ├── all_to_all_v       # AlltoAll、AlltoAllV、AlltoAllVC算子实现
|        ├── batch_send_recv    # BatchSendRecv算子实现
|        ├── broadcast          # Broadcast算子实现
|        ├── op_common          # 算子通用组件
|        │   ├── executor       # 执行器
|        │   ├── selector       # 算法选择器
|        │   ├── template       # 算法模板
|        │   └── topo           # 通信域拓扑信息获取和转换
|        ├── recv               # Recv算子实现
|        ├── reduce             # Reduce算子实现
|        ├── reduce_scatter     # ReduceScatter算子实现
|        ├── reduce_scatter_v   # ReduceScatterV算子实现
|        ├── scatter            # Scatter算子实现
|        └── send               # Send算子实现
├── include                     # HCCL对外头文件
├── test                        # 测试代码目录
|   ├── ut                      # 单元测试代码目录
|   └── st                      # 系统测试代码目录
├── docs                        # 资料文档目录
├── examples                    # 样例代码目录
└── build.sh                    # 编译构建脚本

1.4 为什么需要HCCL?

在深度学习训练中,随着模型规模的不断增大,单卡训练已经无法满足需求。以GPT-3为例,其参数量高达1750亿,单张显卡的显存根本无法容纳。分布式训练成为必然选择,而分布式训练的核心挑战之一就是多卡之间的数据通信

HCCL正是为解决这个问题而生:

三大并行场景

并行方式

说明

HCCL作用

数据并行

多张卡同时训练,每张卡处理不同数据

同步梯度,确保模型一致性

模型并行

模型切分到多张卡,每张卡处理不同层

传递中间结果,协调计算

流水线并行

不同层在不同卡上,形成流水线

传递激活值,减少等待时间


二、库亮点

2.1 高性能通信

HCCL针对NPU的硬件架构进行了深度优化:

特性

说明

性能提升

HCCS互联

利用处理器间的高速互联通道

带宽高达392GB/s

RDMA支持

支持远程直接内存访问

减少CPU开销,降低延迟

拓扑感知

自动识别硬件拓扑

选择最优通信路径

融合通信

多个小通信操作合并

减少通信次数,提升效率

2.2 丰富的通信原语

HCCL支持完整的集合通信原语,覆盖分布式训练的所有通信需求:

原语

功能

典型场景

示意图

Broadcast

一对多广播

参数初始化

[0,0,0] → [x,x,x]

AllReduce

全局规约

梯度同步

[a,b] → [a⊕b,a⊕b]

AllGather

全局收集

模型并行

[a],[b] → [a,b],[a,b]

ReduceScatter

规约分散

梯度分片

[a,b] → [a⊕b的切片]

AlltoAll

全交换

专家模型

数据重分布

Send/Recv

点对点通信

流水线并行

直接传递

2.3 框架无缝集成

HCCL与主流深度学习框架深度集成,开发者可以像使用NCCL一样使用HCCL:

# PyTorch中使用HCCL
import torch
import torch_npu  # CANN PyTorch适配

# 初始化分布式环境
torch.distributed.init_process_group(backend='hccl')

# 后续代码与使用NCCL完全一致

2.4 灵活的拓扑配置

支持多种硬件拓扑:

  • 单机多卡:Notebook内多张NPU通过HCCS互联
  • 多机多卡:Notebook间通过RoCE/InfiniBand互联

三、应用场景

3.1 大模型训练

当前大语言模型(LLM)训练是HCCL最主要的应用场景:


┌─────────────────────────────────────────────────────────────────┐
│                    多机分布式训练架构                            │
│                                                                 │
│  ┌─────────────────────────┐   ┌─────────────────────────┐     │
│  │      Notebook A            │   │      Notebook B            │     │
│  │  ┌─────────────────┐    │   │  ┌─────────────────┐    │     │
│  │  │   NPU 910B      │    │   │  │   NPU 910B      │    │     │
│  │  │   Rank 0        │    │   │  │   Rank 1        │    │     │
│  │  └────────┬────────┘    │   │  └────────┬────────┘    │     │
│  │           │             │   │           │             │     │
│  │     ┌─────┴─────┐       │   │     ┌─────┴─────┐       │     │
│  │     │   HCCL    │       │   │     │   HCCL    │       │     │
│  │     │ AllReduce │       │   │     │ AllReduce │       │     │
│  │     └─────┬─────┘       │   │     └─────┬─────┘       │     │
│  └───────────┼─────────────┘   └───────────┼─────────────┘     │
│              │                             │                   │
│              └─────────────┬───────────────┘                   │
│                            │                                   │
│                     ┌──────┴──────┐                            │
│                     │   网络      │                            │
│                     │ Port: 29500 │                            │
│                     └─────────────┘                            │
│                                                                 │
│  梯度同步、参数更新、激活值传递                                  │
└─────────────────────────────────────────────────────────────────┘

典型应用

  • GPT系列模型训练
  • BERT预训练
  • 文心一言、盘古等国产大模型

3.2 分布式推理

大模型推理同样需要分布式支持:

场景

通信需求

HCCL原语

张量并行

层间激活传递

AllReduce

流水线并行

跨卡数据传递

Send/Recv

专家并行

Token路由

AlltoAll

3.3 科学计算

除AI训练外,HCCL还支持:

  • 气象模拟
  • 分子动力学
  • 流体力学计算

四、上手指南

4.1 环境准备

本文实操环境(两台gitcode Notebook)

配置项

NotebookA

NotebookB

内网IP

10.202.73.94

10.202.73.95

Notebook类型

NPU basic

NPU basic

NPU

1 * NPU 910B

1 * NPU 910B

CPU

16v CPU

16v CPU

内存

64GB

64GB

系统

Ubuntu 22.04

Ubuntu 22.04

CANN

8.5

8.5

Python

3.11

3.11

Jupyter端口

8888

8888

HCCL通信端口

29500

29500

网络配置

  • 两台Notebook通过 29500端口 进行HCCL通信
  • NotebookA作为主节点
  • NotebookB作为从节点

4.2 环境验证

在gitcode上平台上的两个账号下激活两台Notebook,创建新的Jupyter Notebook执行:

import torch
import torch_npu

print(f"PyTorch版本: {torch.__version__}")
print(f"torch_npu版本: {torch_npu.__version__}")
print(f"NPU可用: {torch_npu.npu.is_available()}")
print(f"NPU数量: {torch_npu.npu.device_count()}")

if torch_npu.npu.is_available():
    print(f"NPU名称: {torch_npu.npu.get_device_name(0)}")

结果输出


五、代码示例

5.1 分布式训练脚本(完整版)

以下代码需要在两台Notebook的Jupyter Notebook中分别运行。

NotebookA(10.202.73.94)- Rank 0
"""
HCCL多机分布式训练 - NotebookA (Rank 0)
IP: 10.202.73.94
通信端口: 29500
"""
import os
import torch
import torch.nn as nn
import torch.distributed as dist
import torch_npu
from torch.nn.parallel import DistributedDataParallel as DDP

# ========== 配置区域 ==========
RANK = 0                    # 当前节点编号
WORLD_SIZE = 2              # 总节点数
MASTER_ADDR = '10.202.73.94'  # 主节点IP(NotebookA)
MASTER_PORT = '29500'       # HCCL通信端口
DEVICE_ID = 0               # NPU设备ID
# ==============================

print("="*60)
print("HCCL多机分布式训练 - NotebookA (Rank 0)")
print("="*60)
print(f"本机IP: {MASTER_ADDR}")
print(f"对端IP: 10.202.73.95")
print(f"通信端口: {MASTER_PORT}")
print("="*60)
# 步骤1:设置环境变量
os.environ['RANK'] = str(RANK)
os.environ['WORLD_SIZE'] = str(WORLD_SIZE)
os.environ['MASTER_ADDR'] = MASTER_ADDR
os.environ['MASTER_PORT'] = MASTER_PORT

print(f"RANK: {RANK}")
print(f"WORLD_SIZE: {WORLD_SIZE}")
print(f"MASTER_ADDR: {MASTER_ADDR}")
print(f"MASTER_PORT: {MASTER_PORT}")
# 步骤2:检查NPU状态
print(f"PyTorch版本: {torch.__version__}")
print(f"torch_npu版本: {torch_npu.__version__}")
print(f"NPU可用: {torch_npu.npu.is_available()}")
print(f"NPU数量: {torch_npu.npu.device_count()}")

if torch_npu.npu.is_available():
    print(f"NPU名称: {torch_npu.npu.get_device_name(0)}")
# 步骤3:初始化HCCL分布式环境
# 注意:执行此Cell后,需要等待NotebookB也执行对应的初始化Cell

# 设置NPU设备
torch.npu.set_device(DEVICE_ID)
print(f"✅ 已设置NPU设备: {DEVICE_ID}")

print("正在初始化分布式环境...")
print("⚠️ 请确保NotebookB也执行了初始化Cell")

dist.init_process_group(
    backend='hccl',
    rank=RANK,
    world_size=WORLD_SIZE,
    init_method=f'tcp://{MASTER_ADDR}:{MASTER_PORT}'
)

print("✅ HCCL分布式环境初始化成功!")
print(f"当前Rank: {dist.get_rank()}")
print(f"总进程数: {dist.get_world_size()}")
# 步骤4:AllReduce操作演示
print("\n" + "="*50)
print("AllReduce操作演示")
print("="*50)

tensor = torch.tensor([float(RANK)], device=f'npu:{DEVICE_ID}')
print(f"[Rank {RANK}] 初始值: {tensor.item()}")

# AllReduce求和 - 需要两个Rank同时执行
dist.all_reduce(tensor, op=dist.ReduceOp.SUM)

print(f"[Rank {RANK}] AllReduce结果: {tensor.item()}")
print(f"预期结果: 0 + 1 = 1.0")
# 步骤5:Broadcast操作演示
print("\n" + "="*50)
print("Broadcast操作演示")
print("="*50)

# Rank 0 广播数据
data = torch.tensor([42.0, 100.0, 256.0], device=f'npu:{DEVICE_ID}')
print(f"[Rank {RANK}] 广播数据: {data.tolist()}")

dist.broadcast(data, src=0)

print(f"[Rank {RANK}] Broadcast完成")
# 步骤6:AllGather操作演示
print("\n" + "="*50)
print("AllGather操作演示")
print("="*50)

local_data = torch.tensor([float(RANK * 10)], device=f'npu:{DEVICE_ID}')
print(f"[Rank {RANK}] 本地数据: {local_data.item()}")

gathered_list = [torch.zeros(1, device=f'npu:{DEVICE_ID}') for _ in range(WORLD_SIZE)]
dist.all_gather(gathered_list, local_data)

result = [t.item() for t in gathered_list]
print(f"[Rank {RANK}] AllGather结果: {result}")
print(f"预期结果: [0.0, 10.0]")
# 步骤7:DDP分布式训练演示
print("\n" + "="*50)
print("DDP分布式训练演示")
print("="*50)

class SimpleModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(1024, 4096)
        self.fc2 = nn.Linear(4096, 1024)
        self.relu = nn.ReLU()
    
    def forward(self, x):
        return self.fc2(self.relu(self.fc1(x)))

model = SimpleModel().to(f'npu:{DEVICE_ID}')
model = DDP(model, device_ids=[DEVICE_ID])

print(f"[Rank {RANK}] 模型创建成功")
print(f"模型参数量: {sum(p.numel() for p in model.parameters())}")
# 训练循环
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.MSELoss()

print(f"\n[Rank {RANK}] 开始训练...\n")

for epoch in range(5):
    data = torch.randn(32, 1024, device=f'npu:{DEVICE_ID}')
    target = torch.randn(32, 1024, device=f'npu:{DEVICE_ID}')
    
    output = model(data)
    loss = criterion(output, target)
    
    optimizer.zero_grad()
    loss.backward()  # HCCL自动同步梯度
    optimizer.step()
    
    print(f"[Rank {RANK}] Epoch {epoch+1}/5, Loss: {loss.item():.4f}")

print(f"\n[Rank {RANK}] 训练完成!")
# 步骤8:清理环境
dist.destroy_process_group()
print("✅ 分布式环境已清理")
NotebookB(10.202.73.95)- Rank 1
"""
HCCL多机分布式训练 - NotebookB (Rank 1)
IP: 10.202.73.95
通信端口: 29500
"""
import os
import torch
import torch.nn as nn
import torch.distributed as dist
import torch_npu
from torch.nn.parallel import DistributedDataParallel as DDP

# ========== 配置区域 ==========
RANK = 1                    # 当前节点编号
WORLD_SIZE = 2              # 总节点数
MASTER_ADDR = '10.202.73.94'  # 主节点IP(NotebookA)
MASTER_PORT = '29500'       # HCCL通信端口
DEVICE_ID = 0               # NPU设备ID
# ==============================

print("="*60)
print("HCCL多机分布式训练 - NotebookB (Rank 1)")
print("="*60)
print(f"本机IP: 10.202.73.95")
print(f"主节点IP: {MASTER_ADDR}")
print(f"通信端口: {MASTER_PORT}")
print("="*60)

# 步骤1:设置环境变量
os.environ['RANK'] = str(RANK)
os.environ['WORLD_SIZE'] = str(WORLD_SIZE)
os.environ['MASTER_ADDR'] = MASTER_ADDR
os.environ['MASTER_PORT'] = MASTER_PORT

print(f"RANK: {RANK}")
print(f"WORLD_SIZE: {WORLD_SIZE}")
print(f"MASTER_ADDR: {MASTER_ADDR}")
print(f"MASTER_PORT: {MASTER_PORT}")

# 步骤2:检查NPU状态
print(f"PyTorch版本: {torch.__version__}")
print(f"torch_npu版本: {torch_npu.__version__}")
print(f"NPU可用: {torch_npu.npu.is_available()}")
print(f"NPU数量: {torch_npu.npu.device_count()}")

if torch_npu.npu.is_available():
    print(f"NPU名称: {torch_npu.npu.get_device_name(0)}")
# 步骤3:初始化HCCL分布式环境
# 设置NPU设备
torch.npu.set_device(DEVICE_ID)
print(f"✅ 已设置NPU设备: {DEVICE_ID}")
print("正在初始化分布式环境...")
print(f"⚠️ 连接到主节点 {MASTER_ADDR}:{MASTER_PORT}")

# 初始化进程组
dist.init_process_group(
    backend='hccl',
    rank=RANK,
    world_size=WORLD_SIZE,
    init_method=f'tcp://{MASTER_ADDR}:{MASTER_PORT}'
)

print("✅ HCCL分布式环境初始化成功!")
print(f"当前Rank: {dist.get_rank()}")
print(f"总进程数: {dist.get_world_size()}")
# 步骤4:AllReduce操作演示
print("\n" + "="*50)
print("AllReduce操作演示")
print("="*50)

tensor = torch.tensor([float(RANK)], device=f'npu:{DEVICE_ID}')
print(f"[Rank {RANK}] 初始值: {tensor.item()}")

# AllReduce求和 - 需要两个Rank同时执行
dist.all_reduce(tensor, op=dist.ReduceOp.SUM)

print(f"[Rank {RANK}] AllReduce结果: {tensor.item()}")
print(f"预期结果: 0 + 1 = 1.0")
# 步骤5:Broadcast操作演示
print("\n" + "="*50)
print("Broadcast操作演示")
print("="*50)

# Rank 1 接收广播数据
data = torch.zeros(3, device=f'npu:{DEVICE_ID}')
print(f"[Rank {RANK}] 等待接收广播数据...")

dist.broadcast(data, src=0)

print(f"[Rank {RANK}] 接收到的数据: {data.tolist()}")
# 步骤6:AllGather操作演示
print("\n" + "="*50)
print("AllGather操作演示")
print("="*50)

local_data = torch.tensor([float(RANK * 10)], device=f'npu:{DEVICE_ID}')
print(f"[Rank {RANK}] 本地数据: {local_data.item()}")

gathered_list = [torch.zeros(1, device=f'npu:{DEVICE_ID}') for _ in range(WORLD_SIZE)]
dist.all_gather(gathered_list, local_data)

result = [t.item() for t in gathered_list]
print(f"[Rank {RANK}] AllGather结果: {result}")
print(f"预期结果: [0.0, 10.0]")
# 步骤7:DDP分布式训练演示
print("\n" + "="*50)
print("DDP分布式训练演示")
print("="*50)

class SimpleModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(1024, 4096)
        self.fc2 = nn.Linear(4096, 1024)
        self.relu = nn.ReLU()
    
    def forward(self, x):
        return self.fc2(self.relu(self.fc1(x)))

model = SimpleModel().to(f'npu:{DEVICE_ID}')
model = DDP(model, device_ids=[DEVICE_ID])

print(f"[Rank {RANK}] 模型创建成功")
print(f"模型参数量: {sum(p.numel() for p in model.parameters())}")
# 训练循环
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.MSELoss()

print(f"\n[Rank {RANK}] 开始训练...\n")

for epoch in range(5):
    data = torch.randn(32, 1024, device=f'npu:{DEVICE_ID}')
    target = torch.randn(32, 1024, device=f'npu:{DEVICE_ID}')
    
    output = model(data)
    loss = criterion(output, target)
    
    optimizer.zero_grad()
    loss.backward()  # HCCL自动同步梯度
    optimizer.step()
    
    print(f"[Rank {RANK}] Epoch {epoch+1}/5, Loss: {loss.item():.4f}")

print(f"\n[Rank {RANK}] 训练完成!")
# 步骤8:清理环境
dist.destroy_process_group()
print("✅ 分布式环境已清理")

5.2 运行步骤(完整实操流程)

步骤1:激活Notebook

gitcode 平台两个账号下按照如下配置操作激活两台Notebook

激活成功后进入到如下界面:

步骤2:获取Notebook的IP

在NotebookA上打开Terminal获取IP:

ifconfig

在NotebookB上打开Terminal获取IP:

ifconfig

步骤3:创建Notebook

在两台Notebook上分别创建新的Jupyter Notebook文件,文件内容分别为命名为:

  • NotebookA:hccl_rank0.ipynb

其中内容为5.1NotebookA内容。

  • NotebookB:hccl_rank1.ipynb

其中内容为5.1NotebookB内容。

步骤4:执行初始化

重要:按顺序执行!

1.先在NotebookA执行 Cell 1-3(直到初始化分布式环境)

2.再在NotebookB执行 Cell 1-3(初始化会连接到NotebookA)

⚠️ 初始化时需要两个Notebook几乎同时执行,建议间隔不超过30秒

步骤5:同步执行后续操作

初始化成功后,后续的Cell需要两台Notebook几乎同时执行

操作

说明

AllReduce

两台Notebook同时执行,等待对方完成

Broadcast

NotebookA发送,NotebookB接收

AllGather

两台Notebook同时执行

DDP训练

两台Notebook同时执行训练循环

步骤6:验证结果

AllReduce预期结果

[Rank 0] 初始值: 0.0
[Rank 0] AllReduce结果: 1.0

[Rank 1] 初始值: 1.0
[Rank 1] AllReduce结果: 1.0

Broadcast预期结果

[Rank 0] 广播数据: [42.0, 100.0, 256.0]
[Rank 1] 接收到的数据: [42.0, 100.0, 256.0]

AllGather预期结果

[Rank 0] AllGather结果: [0.0, 10.0]
[Rank 1] AllGather结果: [0.0, 10.0]

DDP训练结果

分布式训练演示:

训练循环:

六、最佳实践

6.1 网络优化

优化策略

说明

效果

使用RoCE

RDMA over Converged Ethernet

降低延迟,提升带宽

巨型帧

MTU设置为9000

减少分包开销

绑定CPU核心

进程绑定到特定CPU核心

减少上下文切换

6.2 通信优化

优化策略

说明

效果

梯度累积

减少通信频率

提升吞吐

梯度压缩

传输压缩后的梯度

降低带宽需求

通信计算重叠

通信与计算并行

隐藏通信延迟

6.3 常见问题

问题

原因

解决方案

连接超时

网络不通或端口未开放

检查网络连通性和端口配置

初始化失败

两台Notebook启动时间差太大

尽量同时启动(30秒内)

通信超时

网络不稳定

增大超时时间或检查网络

死锁

操作顺序不一致

确保所有rank执行相同操作

6.4 故障排查

# 检查网络连通性
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
result = sock.connect_ex(('10.202.68.49', 29500))
print(f"端口29500状态: {'开放' if result == 0 else '关闭'}")
sock.close()

# 检查NPU状态
import torch_npu
print(f"NPU状态: {torch_npu.npu.is_available()}")

参考资料

Logo

1331

更多推荐