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

解决 NCCL 多节点通信问题:从 nranks 1 到 busbw 116 MB/s

背景

最近,我尝试在两台服务器(193.0.0.101193.0.0.100)上运行 NCCL 测试程序 all_reduce_perf,以验证 GPU 间的通信性能。测试环境为:

  • 服务器zzp-Z790-D-AX(RTX 4090, CUDA 11.8, 驱动 12020)和 zzp-System-Product-Name(RTX 4060 Ti, CUDA 11.8, 驱动 12080)。
  • 网络:千兆以太网(enp4s0eno1)。
  • 目标:实现多节点通信(nranks 2)并获得合理带宽(busbw)。

然而,初始测试遇到了一系列问题,包括编译失败、跨节点通信失败和带宽极低(busbw 0)。本文记录了问题排查和解决过程,希望对遇到类似问题的开发者有所帮助。

问题描述

  1. NCCL 安装目录未明确
    • LD_LIBRARY_PATH 未包含 NCCL 库路径,导致测试程序可能无法加载库。
  2. 跨节点通信失败
    • 测试输出显示 nranks 1busbw 0,表明 NCCL 仅在一个节点上运行。
  3. 编译错误
    • 重新编译 nccl-tests 时,报错:fatal error: mpi.h: 没有那个文件或目录
  4. MPI 网络配置错误
    • 使用 --mca btl_tcp_if_include enp4s0,eno1 导致 MPI 通信失败。
  5. 低带宽问题
    • 即使通信成功,busbw 仅为 0.0018385 GB/s,远低于千兆以太网预期(~0.1 GB/s)。
  6. 错误接口选择
    • NCCL 日志显示使用了无线接口(如 wlp0s20f3:192.168.112.19),导致性能低下。

排查与解决步骤

1. 确认 NCCL 安装目录

  • 问题LD_LIBRARY_PATH 未包含 NCCL 库路径。
  • 解决
    • 使用 find /usr -name "libnccl*" 找到 NCCL 库:/usr/lib/x86_64-linux-gnu
    • 更新环境变量:
      export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/openmpi/lib:/usr/local/cuda/lib64
      
    • 验证库链接:
      ldd /home/zzp/Documents/code/nccl-tests/build/all_reduce_perf | grep libnccl
      # 输出:libnccl.so.2 => /usr/lib/x86_64-linux-gnu/libnccl.so.2
      

2. 修复编译错误

  • 问题:缺少 MPI 开发库,导致 mpi.h 未找到。
  • 解决
    • 安装 OpenMPI 开发库:
      sudo apt-get install libopenmpi-dev openmpi-bin
      
    • 找到 mpi.h/usr/lib/x86_64-linux-gnu/openmpi/include
    • 重新编译 nccl-tests
      cd /home/zzp/Documents/code/nccl-tests
      make clean
      make MPI=1 CUDA_HOME=/usr/local/cuda NCCL_HOME=/usr/lib/x86_64-linux-gnu MPI_HOME=/usr/lib/x86_64-linux-gnu/openmpi
      
    • 验证编译:
      ls ./build/all_reduce_perf
      ldd ./build/all_reduce_perf | grep -E "libnccl|libmpi"
      

3. 修复 MPI 网络配置

  • 问题--mca btl_tcp_if_include enp4s0,eno1 无效,hostfile 格式错误。
  • 解决
    • 创建正确的 hostfile
      echo "193.0.0.101 slots=1" > hosts.txt
      echo "193.0.0.100 slots=1" >> hosts.txt
      
    • 测试命令(初始):
      mpirun -np 2 --hostfile hosts.txt \-x NCCL_DEBUG=TRACE \-x NCCL_IB_DISABLE=1 \-x NCCL_SOCKET_IFNAME= \-x TORCH_NCCL_BLOCKING_WAIT=1 \-x LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/openmpi/lib:/usr/local/cuda/lib64 \/home/zzp/Documents/code/nccl-tests/build/all_reduce_perf -b 8 -e 8M -f 2 > nccl_trace.log 2>&1
      
    • 验证 MPI 通信:
      #include <mpi.h>
      #include <stdio.h>
      int main(int argc, char** argv) {MPI_Init(&argc, &argv);int rank, size;MPI_Comm_rank(MPI_COMM_WORLD, &rank);MPI_Comm_size(MPI_COMM_WORLD, &size);printf("Rank %d of %d on host %s\n", rank, size, getenv("HOSTNAME"));MPI_Finalize();return 0;
      }
      
      mpicc -o mpi_test mpi_test.c
      scp mpi_test 193.0.0.100:/home/zzp/mpi_test
      mpirun -np 2 --hostfile hosts.txt /home/zzp/mpi_test
      

4. 解决低带宽问题

  • 问题:NCCL 使用了无线接口(wlp0s20f3:192.168.112.19),导致 busbw 0.0018385 GB/s
  • 解决
    • 强制 NCCL 使用有线接口:
      mpirun -np 2 --hostfile hosts.txt \-x NCCL_DEBUG=TRACE \-x NCCL_IB_DISABLE=1 \-x NCCL_SOCKET_IFNAME=enp4s0,eno1 \-x TORCH_NCCL_BLOCKING_WAIT=1 \-x LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/openmpi/lib:/usr/local/cuda/lib64 \/home/zzp/Documents/code/nccl-tests/build/all_reduce_perf -b 1M -e 128M -f 2 > nccl_trace.log 2>&1
      
    • 调整测试数据量(-b 1M -e 128M),带宽提升到 0.116373 GB/s(~116 MB/s)。
    • 日志确认使用正确接口:
      NET/Socket : Using [0]enp4s0:193.0.0.101<0>
      NET/Socket : Using [0]eno1:193.0.0.100<0>
      

最终结果

  • 跨节点通信nranks 2,两节点(193.0.0.101193.0.0.100)成功通信。
  • 带宽busbw 0.116373 GB/s(~116 MB/s),符合千兆以太网预期。
  • 接口:使用有线接口 enp4s0eno1,避免了无线接口干扰。
  • 日志nccl_trace.log 确认通信路径正确,无错误。
http://www.dtcms.com/a/292716.html

相关文章:

  • 02-netty基础-java四种IO模型
  • 二、计算机网络技术——第3章:数据链路层
  • Yocto meta-toradex-security layer 使用 TI AM62 安全启动功能
  • vscode,cursor,Trae终端不能使用cnpm、npm、pnpm命令解决方案
  • QT RCC 文件
  • Hadoop调度器深度解析:FairScheduler与CapacityScheduler的优化策略
  • PHP获取淘宝拍立淘(以图搜图)API接口操作详解
  • Ext4文件系统全景解析
  • 【n8n教程笔记——工作流Workflow】文本课程(第一阶段)——1、导航编辑器界面(Navigating the editor UI)介绍
  • DOM编程全解析:操作、事件与存储实战指南
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现水下鱼类识别(C#代码,UI界面版)
  • 深入浅出Proxy与Reflect:从“黑中介“到“数据管家“的进阶之路
  • 【openssl生成自签证书】
  • Redis持久化-AOF
  • OpenCV 零基础到项目实战 | DAY 1:图像基础与核心操作
  • UE5 UI 安全区
  • 基于springboot的医院资源管理系统(源码+论文)
  • nodejs:告别全局安装,npx 命令详解及其与 npm 的区别
  • 网络安全渗透攻击案例实战:某公司内网为目标的渗透测试全过程
  • 如何永久删除安卓设备中的照片(已验证)
  • 2025 年非关系型数据库全面指南:类型、优势
  • 【Android】Popup menu:弹出式菜单
  • 小玩 Lifecycle
  • imx6ull-系统移植篇17——linux顶层 Makefile(上)
  • ZooKeeper学习专栏(五):Java客户端开发(原生API)详解
  • map和set的应用与模拟实现
  • UNet改进(24):注意力机制-从基础原理到高级融合策略
  • LLC协议
  • 基于 fastapi 的 YOLO 批量目标检测 API:支持单图 / 文件夹自适应处理
  • 前端葵花宝典