分布式模型训练杂录
数据准备:Linux 压缩与文件分发
1. 文件打包与压缩 (tar & zip)
tar 是 Linux 系统下最常用的打包工具,它可以将多个文件或目录打包成一个单独的文件,方便传输和管理。结合不同的压缩算法,tar 还能在打包的同时进行压缩,以节省存储空间。
| 压缩方式 | 文件扩展名 | 速度/压缩率特点 | 兼容性/适用场景 | 示例命令 |
|---|---|---|---|---|
| 仅打包,不压缩 | .tar | 速度最快,无压缩 | 仅打包文件,适合本地归档 | tar -cvf target.tar source_dir |
| gzip 压缩 | .tar.gz | 压缩速度快,压缩率好,通用性强 | 最常用的压缩方式 | tar -czvf target.tar.gz source_dir |
| bzip2 压缩 | .tar.bz2 | 压缩率高于 gzip,速度稍慢 | 需要更高压缩率时 | tar -cjvf target.tar.bz2 source_dir |
| xz 压缩 | .tar.xz | 压缩率最高,速度最慢,资源占用高 | 追求极致压缩率 | tar -cJvf target.tar.xz source_dir |
| zip 压缩 | .zip | 压缩率适中,速度快,跨平台兼容性最好 | 跨平台文件交换 | zip -r target.zip source_dir |
2. 大文件处理:切片与合并
当单个压缩文件过大,不便于网络传输或存储时,我们可以将其分割成多个较小的文件(切片),之后再将它们合并还原。
- 压缩并切片:下面的命令通过管道 (|) 将 tar 的压缩输出流直接传递给 split 命令进行切片。
# 将 data/ 目录压缩并通过管道输出
# split 命令接收标准输入(-),按每个文件2000MB(-b 2000M)的大小进行切分
# -d 使用数字后缀, -a 1 后缀长度为1位
tar -czvf - data/ | split -b 2000M -d -a 1 - "data_tar/data.tar.gz.part-"- 合并与解压:将切片后的文件传输到目标位置后,可以使用 cat 命令将它们合并成一个完整的压缩包,然后正常解压。
# 使用 cat 命令按顺序合并所有 part 文件
cat target.tar.gz.part-* > restored.tar.gz
# 解压合并后的文件
# -x: extract files from an archive
tar -xzvf restored.tar.gz3. 批量远程操作 (pdsh)
在分布式计算或集群环境中,我们常常需要在多台机器上执行相同的命令。pdsh (Parallel Distributed Shell) 就是一个强大的工具,可以让你在多个主机上并行执行命令。
首先,确保你已经安装了 pdsh,并且所有目标主机都可以通过 SSH 无密码登录;其次,需要创建一个包含所有目标主机名称的 hostfile 文件,文件样式如下:
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4在所有主机上创建目录
# -w ^hostfile: 指定目标主机列表文件
pdsh -w ^hostfile 'mkdir /root/data'分发文件到所有主机:使用 rsync 可以高效地将本地文件同步到所有远程主机。
pdsh -w ^hostfile 'rsync -ah --info=progress2 /mnt/public/data/raw.tar /root/data'在所有主机上并行解压:使用 pdsh 在所有主机上同时解压文件。
# -C /root/data/: 指定解压到/root/data/目录
pdsh -w ^hostfile 'tar -xvf /root/data/raw.tar -C /root/data/'在所有主机上验证文件数量:检查解压后的文件数量是否正确。
pdsh -w ^hostfile 'find /root/data/raw -type f | wc -l'在所有主机上并行运行脚本:批量执行 Python 脚本,并将输出重定向到本地日志文件。
pdsh -w ^hostfile 'cd /mnt/workspace/src/ && python validate_images.py'多机多卡分布式训练配置
1. 配置 NCCL 高效通信
NCCL (NVIDIA Collective Communications Library) 是一个为 NVIDIA GPU 优化的多 GPU/多节点通信库,是进行分布式训练的基石。正确的环境配置能确保通信效率,避免常见陷阱。
主机 (Master Node) 环境变量设置
# 开启 NCCL 调试信息,有助于排查通信问题。可设置为 WARN 或 INFO。
export NCCL_DEBUG=INFO
# 禁用 InfiniBand (IB) 和点对点通信 (P2P)。这通常用于在特定硬件或驱动问题下进行故障排除。
export NCCL_IB_DISABLE=1
export NCCL_P2P_DISABLE=1
# 强制 NCCL 使用 Socket 进行网络通信。当 InfiniBand (IB) 网络环境有问题或不可用时,这是一个可靠的备选项。
export NCCL_NET=Socket
# 明确指定 NCCL 和 Gloo 使用的网络接口名称(例如 bond1, eth0)。
# 在多网卡服务器上,这是确保训练流量走在高速网络(如万兆网卡)上的关键设置。
export NCCL_SOCKET_IFNAME=bond1
export GLOO_SOCKET_IFNAME=bond1
# 指定主节点的 IP 地址和通信的端口号
export MASTER_ADDR=x.x.x.x
export MASTER_PORT=8005
# 设置 PyTorch NCCL 阻塞等待,避免在某些网络环境下出现超时问题。
export TORCH_NCCL_BLOCKING_WAIT=1
# 强制使用 Gloo 作为后端通信库,适用于某些特定场景
export USE_GLOO=1
# 可选:启用等待 DNS 解析,适用于动态 IP 环境
export WAIT_DNS_ENABLE=1从机 (Worker Nodes) 环境变量设置
从机只需设置通用通信环境变量,MASTER_ADDR 和 MASTER_PORT 会由 DeepSpeed 或 PyTorch 启动器自动分发,可通过 pdsh 批量设置环境变量,简化多节点集群操作。
# 在 hostfile 中列出的所有主机上,统一设置 NCCL 和 Gloo 使用的网络接口
pdsh -w ^hostfile 'export NCCL_SOCKET_IFNAME=bond1'
pdsh -w ^hostfile 'export GLOO_SOCKET_IFNAME=bond1'2. 分布式训练推理配置
torchrun 分布式训练/推理
对于分布式训练推理任务,PyTorch 提供了 torchrun 工具来替代旧的 torch.distributed.launch。通过 —standalone 模式,torchrun 能自动管理所有后台配置,让您无需设置任何环境变量即可启动分布式程序。
# 传统方式启动单机多卡训练/推理
export MASTER_ADDR=127.0.0.1
export MASTER_PORT=8005
export WORLD_SIZE=8
export RANK=0
python -m torch.distributed.launch --nproc_per_node=8 train_script.py
# 使用 torchrun 启动单机多卡训练/推理
torchrun --standalone --nproc_per_node=8 train_script.py
# 使用 torchrun 启动多机多卡训练/推理
torchrun \
--nnodes=2 \
--nproc_per_node=8 \
--node_rank=0 \
--rdzv_id=my_training_job_001 \
--rdzv_backend=c10d \
--rdzv_endpoint="10.0.0.1:29500" \
train_script.py --your-argsDeepSpeed 分布式训练
DeepSpeed 是一个由微软开发的深度学习优化库,它极大地简化了大规模分布式训练的启动和管理。
启动多机训练时,只需在主节点上将原始的 python 命令替换为 deepspeed 命令,并使用 —hostfile 参数指定节点配置即可,DeepSpeed 会自动处理后续的 SSH 连接和进程启动。
# 原始训练命令
python3 train.py --dataset_path /path/dataset \
--processes_num 8 \
--data_processor mlm
# 使用 DeepSpeed 启动多机多卡训练
deepspeed --hostfile=hostfile \
train.py --dataset_path /path/dataset \
--processes_num 8 \
--data_processor mlm需要注意的是,hostfile 文件中每行指定一个节点的主机名或 IP 地址,以及该节点上可用的 GPU 数量,格式如下:
10.0.0.1 slots=8
10.0.0.2 slots=8
10.0.0.3 slots=8
10.0.0.4 slots=8Accelerate 分布式训练
Accelerate 是由 Hugging Face 提供的一个高层次分布式训练库,旨在简化多设备、多节点训练的复杂性。
使用 accelerate launch 命令可以轻松启动多机多卡训练任务。只需指定主节点地址、端口号以及每个节点的 GPU 数量,Accelerate 会自动处理分布式环境的配置和进程管理。
# 使用 Accelerate 启动多机多卡训练/推理
accelerate launch --config_file accelerate_config.yaml examples/model_training/train.py \
--dataset_base_path /root/data/ \
--dataset_metadata_path /mnt/workspace/metadata.csv \
--model_paths "/mnt/workspace/models/" \
--learning_rate 5e-5 \
--num_epochs 50 \
--output_path "/mnt/workspace/outputs/" \其中 accelerate_config.yaml 文件内容示例,可以根据实际集群环境进行调整:
compute_environment: LOCAL_MACHINE
deepspeed_config:
deepspeed_hostfile: hostfile
deepspeed_multinode_launcher: pdsh
gradient_clipping: 1.0
gradient_accumulation_steps: 4
offload_optimizer_device: none
offload_param_device: none
zero3_init_flag: false
zero_stage: 1
distributed_type: DEEPSPEED
enable_cpu_affinity: false
dynamo_config: {}
fsdp_config: {}
megatron_lm_config: {}
downcast_bf16: 'no'
machine_rank: 0
main_process_ip: x.x.x.x
main_process_port: 8005
main_training_function: main
mixed_precision: bf16
num_machines: 8
num_processes: 64
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: falseDeepSpeed ZeRO 通过将模型参数、梯度和优化器状态分散存储到各 GPU,有效减少显存占用,让超大模型训练成为可能。ZeRO 分为三个阶段,内存优化程度和通信开销逐步提升,适用于不同规模和需求的分布式训练。
| 阶段 | 分区内容 | 内存节省 | 通信/计算开销 | 适用场景与特点 |
|---|---|---|---|---|
| ZeRO-0 | 无(纯数据并行) | 最低 | 低 | 实现最简单,适合小模型或单机多卡场景,易于调试 |
| ZeRO-1 | 仅优化器状态分区 | 低 | 低 | 显著降低优化器状态内存,训练速度影响小,入门首选 |
| ZeRO-2 | 优化器状态 + 梯度分区 | 中高 | 中 | 内存节省与训练效率平衡,最常用,适合多数大模型训练场景 |
| ZeRO-3 | 参数 + 梯度 + 优化器状态分区 | 最高 | 高 | 最大程度减少显存占用,支持超大模型,但通信开销和实现复杂度最高 |
Shell 命令输出重定向与日志记录
| 命令 | 功能说明 | 屏幕显示 | 文件内容 |
|---|---|---|---|
cmd > log.txt | 只记录正常输出到文件 | 无 | 只有正常输出 |
cmd &> log.txt | 记录正常和错误输出到文件 | 无 | 正常输出 + 错误输出 |
cmd | tee log.txt | 同时显示和记录正常输出 | 正常输出 | 只有正常输出 |
cmd 2>&1 | tee log.txt | 同时显示和记录所有输出(推荐) | 正常输出 + 错误输出 | 正常输出 + 错误输出 |
cmd 2>&1 | tee -a log.txt | 同时显示和追加记录所有输出 | 正常输出 + 错误输出 | 追加的(正常输出 + 错误输出) |
- 日常调试推荐:
cmd 2>&1 \| tee log.txt- 既能实时查看输出,又能完整保存日志 - 长期日志记录:
cmd 2>&1 \| tee -a log.txt- 追加模式,适合多次运行的日志记录
