限时福利领取


最近在搭建PyTorch分布式训练环境时,遇到一个典型问题:c10d库报错the ipv6 network addresses of (worker1, 9901) cannot be retrieved (ga...)。经过一番折腾终于解决,记录下排查过程和解决方案,希望对遇到类似问题的同学有所帮助。

问题现象

当启动分布式训练脚本时,日志中突然出现以下错误:

RuntimeError: the ipv6 network addresses of (worker1, 9901) cannot be retrieved (ga...)

用Wireshark抓包可以看到,worker节点间的IPv6连接请求没有得到响应: 抓包截图

这个错误的意思是c10d库(PyTorch的分布式通信后端)尝试通过IPv6地址建立worker间的连接,但地址解析失败了。

根因分析

经过排查发现,问题出在glibc的getaddrinfo()函数上。不同Linux发行版对这个函数的实现有差异:

  • Ubuntu默认会同时尝试IPv4和IPv6地址解析
  • CentOS在某些配置下会优先尝试IPv6
  • 如果网络环境没有正确配置IPv6,就会触发这个错误

深层原因是现代Linux系统默认启用了IPv6协议栈,但很多内网环境实际上并没有部署IPv6网络基础设施。

解决方案

方案1:强制使用IPv4模式

最简单的解决方法是强制PyTorch使用IPv4协议:

torch.distributed.init_process_group(
    backend='nccl',
    init_method='env://',
    addr_family=socket.AF_INET  # 关键参数,强制IPv4
)

方案2:修改系统地址解析配置

对于多节点环境,可以统一修改/etc/gai.conf文件:

# 在所有节点执行
sudo sed -i 's/#precedence ::ffff:0:0/96  100/precedence ::ffff:0:0/96  100/' /etc/gai.conf

或者用Ansible批量配置:

- hosts: all
  tasks:
    - name: Configure IPv4 precedence
      lineinfile:
        path: /etc/gai.conf
        regexp: '^#precedence ::ffff:0:0\/96'
        line: 'precedence ::ffff:0:0/96  100'
        state: present

方案3:容器网络配置

如果使用Docker,需要特别注意网络模式:

# docker-compose.yml示例
services:
  worker:
    network_mode: "host"  # 使用主机网络栈
    environment:
      - NCCL_SOCKET_IFNAME=eth0  # 指定网卡

验证体系

基础连通性测试

在各节点上执行:

# 在控制节点
nc -l 9901

# 在工作节点
nc -zv <controller_ip> 9901

诊断检查清单

在启动训练任务前建议检查:

  1. 节点间ping通
  2. 端口可访问
  3. 防火墙规则
  4. NCCL调试信息
    export NCCL_DEBUG=INFO

生产环境建议

对于正式训练环境,还需要考虑:

  • 多网卡绑定:指定NCCL使用的网卡

    export NCCL_SOCKET_IFNAME=eth0
  • 防火墙配置:开放RDMA所需端口

    # 示例:允许NCCL端口范围
    sudo iptables -A INPUT -p tcp --dport 1024:65535 -j ACCEPT
  • K8s网络插件:建议使用Calico或Weave

动手实验

建议读者尝试以下实验来加深理解:

  1. 设置调试级别观察错误

    import os
    os.environ['GLOG_minloglevel'] = '1'
  2. 修改IPv6配置复现问题

  3. 使用不同解决方案恢复训练

遇到问题欢迎在评论区交流讨论!

实验环境

Logo

音视频技术社区,一个全球开发者共同探讨、分享、学习音视频技术的平台,加入我们,与全球开发者一起创造更加优秀的音视频产品!

更多推荐