Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【教程】PyTorch多机多卡分布式训练的参数说明 | 附通用启动脚本

【教程】PyTorch多机多卡分布式训练的参数说明 | 附通用启动脚本

原创
作者头像
小锋学长生活大爆炸
发布于 2025-04-18 05:14:18
发布于 2025-04-18 05:14:18
82301
代码可运行
举报
文章被收录于专栏:高性能计算高性能计算
运行总次数:1
代码可运行

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~

目录

torchrun

一、什么是 torchrun

二、torchrun 的核心参数讲解

三、torchrun 会自动设置的环境变量

四、torchrun 启动过程举例

机器 A(node_rank=0)上运行

机器 B(node_rank=1)上运行

五、小结表格

PyTorch

一、背景回顾

二、init_process_group

三、脚本中通常的典型写法

通用启动脚本


torchrun 与 torch.multiprocessing.spawn 的对比可以看这篇: 【知识】torchrun 与 torch.multiprocessing.spawn 的对比

torchrun

一、什么是 torchrun

torchrun 是 PyTorch 官方推荐的分布式训练启动器,它的作用是:

  • 启动 多进程分布式训练(支持多 GPU,多节点)
  • 自动设置每个进程的环境变量
  • 协调节点之间建立通信

二、torchrun 的核心参数讲解

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
torchrun \
  --nnodes=2 \
  --nproc_per_node=2 \
  --node_rank=0 \
  --master_addr=192.168.5.228 \
  --master_port=29400 \
  xxx.py

🔹 1. --nnodes(Number of Nodes)

  • 表示参与训练的总机器数
  • 你有几台服务器,就写几。
  • 在分布式训练中,一个 node 就是一台物理或虚拟的主机。
  • node的编号从0开始。

✅ 例子:你用 2 台机器 → --nnodes=2


🔹 2. --nproc_per_node(Processes Per Node)

  • 表示每台机器上要启动几个训练进程。
  • 一个进程对应一个 GPU,因通常设置为你机器上要用到的GPU数。
  • 因此,整个分布式环境下,总训练进程数 = nnodes * nproc_per_node

✅ 例子:每台机器用了 2 张 GPU → --nproc_per_node=2


🔹 3. --node_rank

  • 表示当前机器是第几台机器
  • 从 0 开始编号,必须每台机器都不同!

✅ 例子:

机器 IP

node_rank

192.168.5.228

0

192.168.5.229

1


🔹 4. --master_addr--master_port

  • 指定主节点的 IP 和端口,用于 rendezvous(进程对齐)和通信初始化。
  • 所有机器必须填写相同的值!

✅ 建议:

  • master_addr 就是你指定为主节点的那台机器的 IP
  • master_port 选一个未被占用的端口,比如 29400

三、torchrun 会自动设置的环境变量

当用 torchrun 启动后,它会自动给每个进程设置这些环境变量

环境变量

含义

RANK

当前进程在全局中的编号(0 ~ world_size - 1)

LOCAL_RANK

当前进程在本机中的编号(0 ~ nproc_per_node - 1)

WORLD_SIZE

总进程数 = nnodes * nproc_per_node

你可以在训练脚本里用 os.environ["RANK"] 来读取这些信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import os
rank = int(os.environ["RANK"])
local_rank = int(os.environ["LOCAL_RANK"])
world_size = int(os.environ["WORLD_SIZE"])

示例分配图:

四、torchrun 启动过程举例

假设:

  • 有 2 台机器
  • 每台机器有 2 个 GPU
  • 总共会启动 4 个进程

机器 A(node_rank=0)上运行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
torchrun \
  --nnodes=2 \
  --nproc_per_node=2 \
  --node_rank=0 \
  --master_addr=192.168.5.228 \
  --master_port=29400 \
  xxx.py

机器 B(node_rank=1)上运行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
torchrun \
  --nnodes=2 \
  --nproc_per_node=2 \
  --node_rank=1 \
  --master_addr=192.168.5.228 \
  --master_port=29400 \
  xxx.py

torchrun 给每个进程编号的顺序(分配 RANK / LOCAL_RANK)

torchrun 按照每台机器上 node_rank 的顺序,并在每台机器上依次启动 LOCAL_RANK=0, 1, ..., n-1,最后合成 RANK。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
RANK = node_rank × nproc_per_node + local_rank

Step 1:按 node_rank 升序处理(node 0 → node 1) Step 2:每个 node 内部从 local_rank=0 开始递增


本质上:torchrun 是主从结构调度的

  • 所有 node 启动后,都会和 master_addr 通信。
  • master 会统一收集所有 node 的状态。
  • 每个 node 根据你给的 node_rank 自行派生 local_rank=0~n-1
  • 所有节点通过 RANK = node_rank * nproc_per_node + local_rank 得到自己的全局编号。

这个机制是 可预测、可控、可复现 的。


📦 node_rank=0 (机器 1) ├── local_rank=0 → RANK=0 └── local_rank=1 → RANK=1 📦 node_rank=1 (机器 2) ├── local_rank=0 → RANK=2 └── local_rank=1 → RANK=3

最终分配:

Node Rank

Local Rank

Global Rank (RANK)

使用 GPU

0

0

0

0

0

1

1

1

1

0

2

0

1

1

3

1

五、小结表格

参数

作用

设置方式

--nnodes

总节点数

你写在命令里

--nproc_per_node

每台节点的进程数(= GPU 数)

你写在命令里

--node_rank

当前机器编号(0开始)

每台机器唯一

--master_addr

主节点 IP(所有节点需一致)

你设置

--master_port

主节点端口(所有节点需一致)

你设置

RANK

当前进程在所有进程中的编号

torchrun 自动设置

LOCAL_RANK

当前进程在本节点上的编号

torchrun 自动设置

WORLD_SIZE

总进程数 = nnodes * nproc_per_node

自动设置


PyTorch

PyTorch 的分布式通信是如何通过 init_process_grouptorchrun 生成的环境变量配合起来工作的。

一、背景回顾

你已经用 torchrun 启动了多个训练进程,并且 torchrun 为每个进程自动设置了这些环境变量:

变量名

含义

RANK

当前进程的全局编号(从 0 开始)

LOCAL_RANK

本机上的编号(一般等于 GPU ID)

WORLD_SIZE

总进程数

MASTER_ADDR

主节点的 IP

MASTER_PORT

主节点用于通信的端口

那么 这些变量是如何参与进程通信初始化的? 这就涉及到 PyTorch 的核心函数:


二、init_process_group

torch.distributed.init_process_group 是 PyTorch 初始化分布式通信的入口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
torch.distributed.init_process_group(
    backend="nccl",  # 或者 "gloo""mpi"
    init_method="env://",  # 通过环境变量读取设置
)

关键点:

  • backend="nccl":推荐用于 GPU 分布式通信(高性能)
  • init_method="env://":表示通过环境变量来初始化

你不需要自己设置 RANK / WORLD_SIZE / MASTER_ADDR,只要写:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import torch.distributed as dist

dist.init_process_group(backend="nccl", init_method="env://")

PyTorch 会自动去环境中读这些变量:

  • RANK → 当前进程编号
  • WORLD_SIZE → 总进程数
  • MASTER_ADDRMASTER_PORT → 主节点 IP 和端口

然后就能正确初始化所有通信进程。

三、脚本中通常的典型写法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import os
import torch

# 初始化 PyTorch 分布式通信环境
torch.distributed.init_process_group(backend="nccl", init_method="env://")

# 获取全局/本地 rank、world size
rank = int(os.environ.get("RANK", -1))
local_rank = int(os.environ.get("LOCAL_RANK", -1))
world_size = int(os.environ.get("WORLD_SIZE", -1))

# 设置 GPU 显卡绑定
torch.cuda.set_device(local_rank)
device = torch.device("cuda")

# 打印绑定信息
print(f"[RANK {rank} | LOCAL_RANK {local_rank}] Using CUDA device {torch.cuda.current_device()}: {torch.cuda.get_device_name(torch.cuda.current_device())} | World size: {world_size}")

这段代码在所有进程中都一样写,但每个进程启动时带的环境变量不同,所以最终 ranklocal_rankworld_size 就自然不同了。

通用启动脚本

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/bin/bash

# 设置基本参数
MASTER_ADDR=192.168.5.228           # 主机IP
MASTER_PORT=29400                   # 主机端口
NNODES=2                            # 参与训练的总机器数
NPROC_PER_NODE=2                    # 每台机器上的进程数

# 所有网卡的IP地址,用于筛选
ALL_LOCAL_IPS=$(hostname -I)
# 根据本机 IP 配置通信接口
if [[ "$ALL_LOCAL_IPS" == *"192.168.5.228"* ]]; then
  NODE_RANK=0                       # 表示当前机器是第0台机器
  IFNAME=ens1f1np1  
  mytorchrun=~/anaconda3/envs/dglv2/bin/torchrun
elif [[ "$ALL_LOCAL_IPS" == *"192.168.5.229"* ]]; then
  NODE_RANK=1                       # 表示当前机器是第1台机器
  IFNAME=ens2f1np1
  mytorchrun=/opt/software/anaconda3/envs/dglv2/bin/torchrun
else
  exit 1
fi

# 设置 RDMA 接口
export NCCL_IB_DISABLE=0            # 是否禁用InfiniBand
export NCCL_IB_HCA=mlx5_1           # 使用哪个RDMA接口进行通信
export NCCL_SOCKET_IFNAME=$IFNAME   # 使用哪个网卡进行通信
export NCCL_DEBUG=INFO              # 可选:调试用
export GLOO_IB_DISABLE=0            # 是否禁用InfiniBand
export GLOO_SOCKET_IFNAME=$IFNAME   # 使用哪个网卡进行通信
export PYTHONUNBUFFERED=1           # 实时输出日志

# 启动分布式任务
$mytorchrun \
  --nnodes=$NNODES \
  --nproc_per_node=$NPROC_PER_NODE \
  --node_rank=$NODE_RANK \
  --master_addr=$MASTER_ADDR \
  --master_port=$MASTER_PORT \
  cluster.py

## 如果想获取准确报错位置,可以加以下内容,这样可以同步所有 CUDA 操作,错误不会“延迟触发”,你会看到确切是哪一行代码出了问题:
## CUDA_LAUNCH_BLOCKING=1 torchrun ...

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
PyTorch分布式训练简介
分布式训练已经成为如今训练深度学习模型的一个必备工具,但pytorch默认使用单个GPU进行训练,如果想用使用多个GPU乃至多个含有多块GPU的节点进行分布式训练的时候,需要在代码当中进行修改,这里总结一下几种使用pytorch进行分布式训练的方式。
狼啸风云
2020/02/13
5K0
Pytorch 分布式训练
即进程组。默认情况下,只有一个组,一个 job 即为一个组,也即一个 world。
肉松
2020/09/07
2.5K0
Pytorch 分布式训练
深入理解Pytorch中的分布式训练
作者:台运鹏 (正在寻找internship...) 主页:https://yunpengtai.top
zenRRan
2023/01/12
1.4K0
深入理解Pytorch中的分布式训练
[源码解析] PyTorch分布式(5) ------ DistributedDataParallel 总述&如何使用
本文是 PyTorch 分布式系列的第五篇,以几篇官方文档的翻译为基础,加入了自己的一些思考,带领大家进入DistributedDataParallel,在后续会用5~6篇左右做深入分析。
罗西的思考
2021/11/18
2.2K0
[源码解析] PyTorch分布式(5) ------ DistributedDataParallel 总述&如何使用
【Ubuntu】分布式训练/pycharm远程开发
摸到了组里配备的多卡服务器,对于一个习惯单卡环境的穷学生来说,就像是鸟枪换炮,可惜这炮一时还不会使用,因此就有了此番学习。
zstar
2022/10/08
2K0
【Ubuntu】分布式训练/pycharm远程开发
[源码解析] PyTorch 分布式之弹性训练(2)---启动&单节点流程
在前面的文章之中,我们已经学习了PyTorch 分布式的基本模块,介绍了官方的几个例子,我们接下来会介绍PyTorch的弹性训练,本文是第二篇,重点关注的是如何启动弹性训练,并且可以对系统总体架构有所了解。
罗西的思考
2021/12/24
1.7K0
[源码解析] PyTorch 分布式之弹性训练(2)---启动&单节点流程
Pytorch分布式训练
简单来说,如果数据集较小时推荐尽量使用Map式Dataset,数据量过大、数据量未知、训练内存无法满足时只能使用Iterable式构建Dataset。
iResearch666
2023/09/13
1.4K0
Pytorch分布式训练
Pytorch 分布式模式介绍
数据较多或者模型较大时,为提高机器学习模型训练效率,一般采用多GPU的分布式训练。
狼啸风云
2020/02/13
5.3K1
【PyTorch】PyTorch深度学习框架实战(二):torchrun
不同于TensorFlow、Caffe、CNTK等静态神经网络:网络构建一次反复使用,如果修改了网络不得不重头开始。
LDG_AGI
2024/08/13
2.5K0
【PyTorch】PyTorch深度学习框架实战(二):torchrun
Pytorch中的分布式神经网络训练
随着深度学习的多项进步,复杂的网络(例如大型transformer 网络,更广更深的Resnet等)已经发展起来,从而需要了更大的内存空间。经常,在训练这些网络时,深度学习从业人员需要使用多个GPU来有效地训练它们。在本文中,我将向您介绍如何使用PyTorch在GPU集群上设置分布式神经网络训练。
deephub
2021/01/12
1.4K0
Pytorch中的分布式神经网络训练
【知识】torchrun 与 torch.multiprocessing.spawn 的对比
torchrun 和 torch.multiprocessing.spawn 都是在 PyTorch 中用于并行化和分布式训练的工具,但它们在使用场景和实现方式上有所不同。
小锋学长生活大爆炸
2025/04/09
1720
云原生的弹性 AI 训练系列之二:PyTorch 1.9.0 弹性分布式训练的设计与实现
高策,腾讯高级工程师,Kubeflow 社区训练和自动机器学习工作组 Tech Lead,负责腾讯云 TKE 在 AI 场景的产品研发和支持工作。 背景 机器学习工作负载与传统的工作负载相比,一个比较显著的特点是对 GPU 的需求旺盛。在之前的文章中(公有云上构建云原生 AI 平台的探索与实践 - GOTC 技术论坛分享回顾 和 云原生的弹性 AI 训练系列之一:基于 AllReduce 的弹性分布式训练实践)介绍过,目前 GPU 的显存已经不足以跟上模型参数规模的发展。随着 Transformer 等新
腾讯云原生
2021/08/26
1.4K0
Pytorch 多卡并行训练
DataParallel 使用起来非常方便,我们只需要用 DataParallel 包装模型,再设置一些参数即可。需要定义的参数包括:参与训练的 GPU 有哪些,device_ids=gpus;用于汇总梯度的 GPU 是哪个,output_device=gpus[0] 。DataParallel 会自动帮我们将数据切分 load 到相应 GPU,将模型复制到相应 GPU,进行正向传播计算梯度并汇总:
为为为什么
2022/08/09
4.2K0
Pytorch 多卡并行训练
[源码解析] PyTorch 分布式(4)------分布式应用基础概念
本文以 PyTorch 官方文档 https://pytorch.org/tutorials/intermediate/dist_tuto.html 为基础,对如何编写分布式进行了介绍,并且加上了自己的理解。
罗西的思考
2021/11/16
2.8K1
[源码解析] PyTorch 分布式(4)------分布式应用基础概念
PyTorch 2.2 中文官方教程(十八)
在大规模训练 AI 模型是一项具有挑战性的任务,需要大量的计算能力和资源。同时,处理这些非常大模型的训练也伴随着相当大的工程复杂性。PyTorch FSDP,在 PyTorch 1.11 中发布,使这变得更容易。
ApacheCN_飞龙
2024/02/05
3890
PyTorch 2.2 中文官方教程(十八)
Pytorch中的Distributed Data Parallel与混合精度训练(Apex)
Distributed data parallel training in Pytorchyangkky.github.io
磐创AI
2021/01/12
1.2K0
Pytorch中的Distributed Data Parallel与混合精度训练(Apex)
GPU捉襟见肘还想训练大批量模型?谁说不可以
2018 年的大部分时间我都在试图训练神经网络时克服 GPU 极限。无论是在含有 1.5 亿个参数的语言模型(如 OpenAI 的大型生成预训练 Transformer 或最近类似的 BERT 模型)还是馈入 3000 万个元素输入的元学习神经网络(如我们在一篇 ICLR 论文《Meta-Learning a Dynamical Language Model》中提到的模型),我都只能在 GPU 上处理很少的训练样本。
机器之心
2018/11/07
1.6K0
Pytorch中多GPU训练指北
在数据越来越多的时代,随着模型规模参数的增多,以及数据量的不断提升,使用多GPU去训练是不可避免的事情。Pytorch在0.4.0及以后的版本中已经提供了多GPU训练的方式,本文简单讲解下使用Pytorch多GPU训练的方式以及一些注意的地方。
老潘
2023/10/19
1.8K0
Pytorch中多GPU训练指北
【教程】DGL单机多卡分布式GCN训练
梯度同步默认使用Ring-AllReduce进行,重叠了通信和计算。
小锋学长生活大爆炸
2025/05/24
860
【教程】DGL单机多卡分布式GCN训练
[ai学习笔记]分布式训练原理:DeepSeek千卡集群通信优化策略
在人工智能和深度学习快速发展的当下,模型的规模和复杂度不断攀升,对计算资源的需求也日益增长。为了在有限的时间内训练出高性能的深度学习模型,分布式训练技术应运而生。分布式训练通过将模型和数据分布在多个计算节点上并行处理,大大加速了训练过程。DeepSeek等先进的分布式训练系统在大规模集群环境下,通过优化通信策略,实现了高效的节点间通信和协同训练,能够在千卡规模的集群上充分发挥计算潜能,推动了复杂模型的快速训练和应用。
数字扫地僧
2025/03/15
3770
[ai学习笔记]分布式训练原理:DeepSeek千卡集群通信优化策略
相关推荐
PyTorch分布式训练简介
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验