> 技术文档 > LLaMA-Factory多机多卡训练_llamafactory多卡训练

LLaMA-Factory多机多卡训练_llamafactory多卡训练

在这里插入图片描述
为了在多机多卡环境下训练大模型,我们可以使用LLaMA-Factory。

它支持多种常见模型,集成了包括(增量)预训练、(多模态)指令监督微调、奖励模型训练、PPO 训练、DPO 训练、KTO 训练、ORPO 训练等等训练方法,并且有web-ui和命令行两种使用方式,是目前主流的模型训练框架之一。

如何使用LLaMA-Factory

安装LLaMa-Factory

首先按照GitHub上的步骤安装LLaMA Factory。

  • git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
  • cd LLaMA-Factory
  • pip install -e “.[torch,metrics]”

值得注意的是,必须执行第三步,才能使用官方的llamafactory-cli命令执行训练,否则会报错 命令无法找到。

数据准备

关于数据集文件的格式,可参考 data/README_zh.md 的内容。也可以使用 HuggingFace / ModelScope / Modelers 上的数据集或加载本地数据集。

备注
  • 使用自定义数据集时,需要更新 data/dataset_info.json 文件。

多机多卡训练

LLaMA-Factory支持多种多机多卡训练方式,包括DDP,DeepSpeed,FSDP。

针对想要使用 NativeDDP 或 DeepSpeed 两种分布式训练引擎,推荐使用下列命令,区分两种训练引擎仅仅在于训练的yaml参数文件中。

FORCE_TORCHRUN=1 NNODES=2 RANK=0 MASTER_ADDR=192.168.0.1 MASTER_PORT=29500 \\llamafactory-cli train examples/train_lora/llama3_lora_sft.yaml #在主服务器上运行FORCE_TORCHRUN=1 NNODES=2 RANK=1 MASTER_ADDR=192.168.0.1 MASTER_PORT=29500 \\llamafactory-cli train examples/train_lora/llama3_lora_sft.yaml #在第二个服务器上运行,MASTER_ADDR和MASTER_PORT仍写主服务的ip和端口
参数说明
参数名 说明 FORCE_TORCHRUN 是否强制使用torchrun NNODES 节点数量,即使用的机器数目 RANK 各个节点的rank,对于N台机器编号从0到N-1,0表示该机器为主机 MASTER_ADDR 主节点的地址 MASTER_PORT 主节点的端口
备注
  • 使用此方式需要在每台机器上分别运行指令,同时每台机器上都需要安装LLaMA-Factory和相同的conda环境,都需要保存一份要训练的模型文件。
  • 也可以使用 torchrun 指令启动 NativeDDP 引擎或是使用 deepspeed 指令启动 DeepSpeed 引擎进行多机多卡训练,详见官方文档。

DeepSpeed参数配置

使用DeepSpeed需要在yaml参数文件中给出其配置文件地址,例如
deepspeed: examples/deepspeed/ds_z3_config.json

其中ds_z3_config.json可以设置DeepSpeed的一些参数,重要的有:zero_optimization下的stage参数,用于设置ZeRO阶段,关于ZeRO阶段的介绍如下:

  • ZeRO-1: 仅划分优化器参数,每个GPU各有一份完整的模型参数与梯度。
  • ZeRO-2: 划分优化器参数与梯度,每个GPU各有一份完整的模型参数。
  • ZeRO-3: 划分优化器参数、梯度与模型参数。

简单来说:从 ZeRO-1 到 ZeRO-3,阶段数越高,显存需求越小,但是训练速度也依次变慢。此外,设置 offload_param=cpu 参数会大幅减小显存需求,但会极大地使训练速度减慢。因此,如果有足够的显存, 应当使用 ZeRO-1,并且确保 offload_param=none。

其他参数介绍可以参考DeepSpeed 配置 JSON。

常见问题

多台机器间通信问题

在实际测试中,如果一台机器有两个以上的网卡,则可能发生主机无法找到从机网卡,进而无法通信的问题。主机上的常见报错类似下图:

[rank0]:File \"/usr/local/anaconda3/envs/llama_factory_test/lib/python3.10/site-packages/torch/distributed/distributed_c10d.py\", line 3936, in barrier[rank0]:work = default_pg.barrier(opts=opts)[rank0]:torch.distributed.DistBackendError: NCCL error in: ../torch/csrc/distributed/c10d/NCCLUtils.hpp:275, unhandled system error (run with NCCL_DEBUG=INFO for details), NCCL version 2.20.5[rank0]:ncclSystemError: System call (e.g. socket, malloc) or external library call failed or device error. [rank0]:Last error:[rank0]:socketStartConnect: Connect to 193.168.1.1 failed : Software caused connection abort

而193.168.1.1并非从机真正的网卡地址。

解决方案

在从机启动指令时,加入环境变量,控制使用的通信网卡
export NCCL_SOCKET_IFNAME=

断点重训问题

如果想要在某个checkpoint之后继续训练,可以在yaml参数文件中,train参数部分加上 resume_from_checkpoint参数,参数值设置为想要使用的checkpoint文件地址。

但是针对多机多卡环境存在多机模型文件保存问题,即默认情况下,每台机器上保存的模型训练文件不一致,主机上保存完整,而从机并没有保存完全的训练文件。在断点重训时会导致从机报错,找不到部分训练文件:

[rank1]:File \"/usr/Anaconda/install/envs/llama_factory_test/lib/python3.10/site-packages/transformers/trainer_callback.py\", line 148, in load_from_json[rank1]:with open(json_path, \"r\", encoding=\"utf-8\") as f:[rank1]:FileNotFoundError: [Errno 2] No such file or directory: \'/usr/chl/LLaMA-Factory/multi_test_output/checkpoint-500/trainer_state.json\'

解决方案

解决方案是在一开始训练时在yaml参数文件中加入save_on_each_node: true,这样将会在所有机器上保存模型和优化器权重,之后就可以断点重训。

而如果一开始没有加这个参数,可以在将主机上的checkpoint文件夹复制到从机,再把从机单独保存的bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt文件放到global_step文件夹下后,可以正常继续训练,可以看到训练从500继续。
在这里插入图片描述
此外,仅仅将主机的checkpoint-500文件夹下除了global_step500外的文件拷贝到从机的checkpoint-500文件下也仍然会报错,还需将主机global_step500下mp_rank_00_model_states.pt文件拷贝到从机中。

因此,多机多卡下训练模型,使用共享文件系统是最方便的做法。