PyTorch分布式训练常见错误包括端口被占、MASTER_ADDR配置错误、init_process_group超时及torchrun环境变量冲突;需检查端口占用、使用真实IP、确保WORLD_SIZE与RANK一致、避免手动设置torchrun管理的环境变量。

PyTorch分布式训练报错 RuntimeError: Address already in use
端口被占是初始化失败最常见原因,不是代码写错了,而是本地已有进程(比如上一次没杀干净的 python 或 torch.distributed 进程)绑定了 MASTER_PORT。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 先用
lsof -i :<code>MASTER_PORT(macOS/Linux)或netstat -ano | findstr :<code>MASTER_PORT(Windows)查占用进程 - 确认无用后直接 kill:
kill -9 <code>PID(Linux/macOS)或taskkill /F /PID <code>PID(Windows) - 更稳妥的做法:每次启动前换一个随机端口,比如用
export MASTER_PORT=$((10000 + $RANDOM % 1000)) - 别用默认的 29500 —— 它太常见,CI/本地多任务并行时极易冲突
MASTER_ADDR 设成本机 localhost 却在多机训练中失败
单机多卡能跑不代表多机通,localhost 在每台机器上都指向自己,跨机器根本连不上。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 必须设为可被所有节点访问的真实 IP,比如主节点网卡地址(非
127.0.0.1、非localhost、非 Docker 内网 IP) - 运行前先手动 ping 测试:
ping <code>MASTER_ADDR从所有 worker 节点执行,不通就别往下试 - 如果走 SSH 登录训练,注意云服务器安全组是否放行了
MASTER_PORT端口(TCP) - Docker 场景下,避免用
--network=host外还设localhost—— 容器内localhost不等于宿主机网络命名空间
init_process_group 调用超时卡死,日志停在 initializing process group
这不是程序卡住,是等待其他 rank 连接超时。PyTorch 默认等 300 秒,期间只要有一个 rank 没 join,全部挂起。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 检查
WORLD_SIZE和实际启动的进程数是否一致 —— 少启一个 rank,其余全等死 - 确认所有节点的
RANK值唯一且连续(从 0 开始),比如 4 卡 2 机,RANK 应为 0~3,不能跳号或重复 - 临时加
timeout=datetime.timedelta(seconds=60)到init_process_group参数里,快速暴露连接问题 - 别在 Jupyter 或 IDE 的交互式环境里调
init_process_group—— 它依赖 fork/spawn 子进程,和 notebook 的执行模型不兼容
使用 torchrun 启动却提示找不到 MASTER_ADDR
torchrun 会自动设置 MASTER_ADDR 和 MASTER_PORT,但仅限于它自己管理的进程;一旦你在脚本里又手动读取或覆盖这些变量,就会混乱。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 启动命令里不要 export
MASTER_ADDR:torchrun --nproc_per_node=2 train.py就够了 - 脚本里删掉所有类似
os.environ.get("MASTER_ADDR", ...)的 fallback 逻辑 ——torchrun保证它们存在 - 如果要用自定义地址,改用
--master_addr和--master_port参数传给torchrun,而不是设环境变量 - 混用
torch.distributed.run(旧名)和手写init_process_group时,注意前者默认用env://初始化方式,后者若写成tcp://...会冲突
真正麻烦的从来不是怎么写 init,而是哪台机器漏配了防火墙、哪个 rank 的启动命令少了个 --nproc_per_node、或者 Docker 容器压根没挂载宿主机的网卡路由。分布式不是“写对就行”,是“所有环节同时对”。


















