You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch分布式与多进程异常求助:进程执行全脚本且程序冻结

问题1:为何spawn创建的进程会执行output_0部分?

你犯了一个核心错误:同时混用了torchrun和torch.multiprocessing.spawn。

torchrun本身就是PyTorch官方用来启动分布式多进程的工具,它会根据--nproc_per_node参数自动创建对应数量的进程,每个进程都会完整执行你的脚本代码。而你在if __name__ == '__main__':块里又调用了mp.spawn,相当于每个torchrun启动的进程都会再创建world_size个子进程,形成了进程嵌套。

那些重复的ngpus = 4 world_size = 4输出,本质是每个torchrun启动的进程都进入了__main__代码块执行了print语句,并非spawn创建的子进程导致的。

问题2:为何程序输出部分内容后冻结?

主要有两个原因:

  1. 进程嵌套引发的资源冲突与死锁:torchrun创建的4个进程各自通过mp.spawn再生成4个子进程,总计16个子进程加4个父进程,大量进程同时初始化NCCL进程组,极易引发资源竞争和死锁。
  2. 未正确清理分布式进程组:你的print_tensors函数仅初始化了dist.init_process_group,但函数结束时没有调用dist.destroy_process_group()释放资源。分布式进程在未正确销毁进程组的情况下,会一直等待同步信号,导致程序挂起。

修复方案

你需要二选一使用启动方式,不能混用。推荐采用torchrun的标准写法:

修改后的脚本:

import os
import torch
import torch.cuda as cuda
import torch.distributed as dist


def main():
    rank = int(os.environ['RANK'])
    world_size = int(os.environ['WORLD_SIZE'])
    cuda.set_device(rank)
    dist.init_process_group(backend='nccl', init_method='env://', world_size=world_size)
    
    print(f'{rank} -> {torch.randn(2)}')
    
    # 必须销毁进程组,保证进程正常退出
    dist.destroy_process_group()


if __name__ == '__main__':
    main()

启动命令保持不变:

torchrun \
    --nnodes=1 \
    --nproc_per_node=4 \
    test.py \

修改后,torchrun会为每个GPU创建一个独立进程,每个进程执行main函数,完成初始化、打印、资源清理的完整流程,不会再出现重复输出和冻结问题。

单GPU运行时正常只是巧合——此时torchrun仅创建1个进程,没有嵌套,且单进程下分布式进程组的初始化/销毁不会触发死锁,但这并非正确的分布式写法。

内容的提问来源于stack exchange,提问作者Mecreative

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:41:12