27 KiB
利用AReaL提升大语言模型推理能力:中文教程
前置要求
硬件要求
为了能正常完成训练流程,请参照下表确认你的硬件是否满足要求:
模型大小 | 1.5B | 1.5B | 1.5B | 7B | 7B | 32B |
---|---|---|---|---|---|---|
节点 | 1 | 4 | 16 | 4 | 16 | 16 |
GPU | 8 张 H800 | 每节点 8 张 H800 | 每节点 8 张 H800 | 每节点 8 张 H800 | 每节点 8 张 H800 | 每节点 8 张 H800 |
CPU | 48 核 | 每节点 48 核 | 每节点 48 核 | 每节点 48 核 | 每节点 48 核 | 每节点 48 核 |
内存 | 1 TB | 每节点 1 TB | 每节点 1 TB | 每节点 1 TB | 每节点 1 TB | 每节点 1 TB |
通信 | NVSwitch | NVSwitch+RoCE 带宽 3.2 Tbps | NVSwitch+RoCE 带宽 3.2 Tbps | NVSwitch+RoCE 带宽 3.2 Tbps | NVSwitch+RoCE 带宽 3.2 Tbps | NVSwitch+RoCE 带宽 3.2 Tbps |
存储 | 1TB | 共享存储(NAS)10TB | 共享存储(NAS)10TB | 共享存储(NAS)10TB | 共享存储(NAS)10TB | 共享存储(NAS)10TB |
BatchSize x GroupSize | 512x16 | 512x16 | 512x16 | 512x16 | 512x16 | 512x32 |
单步训练时间(秒) | 3461 | 997 | 391 | 2275 | 815 | 6707 |
训练至收敛需要步数 | ~250 | ~250 | ~250 | ~400 | ~400 | - |
总训练时间(小时) | ~240 | ~69 | ~27 | ~252 | ~90 | - |
关于硬件要求的说明:
-
GPU 需要 80GB 显存,可以选择同级别其他 GPU 型号。
-
单节点训练时可以使用本地存储,但多节点训练必须要提供共享存储,否则无法进行训练。
-
目前32B模型没有训练出有意义的结果,所以无法估计训练到收敛需要的步数和时间。
软件要求
本教程提供 Docker镜像。以下是经过测试的软件版本,可以参考如下软件版本进行配置。
版本说明 | |
---|---|
OS | CentOS 7 / Ubuntu 22.04 或其他满足下方软件运行的系统 |
NVIDIA Driver | 版本:550.127.08 |
CUDA | 版本:12.5 |
Git LFS | 参考:Git LFS 安装指南 主要用于下载模型,数据集,AReaL 工程代码 |
Docker | 版本:27.5.1 |
NVIDIA Container Toolkit | NVIDIA Container Toolkit 安装指南 |
镜像 | ghcr.io/inclusionai/areal-runtime:v0.2.0 这个镜像中包含运行依赖和 Ray 的相关组件 |
由于 NVIDIA Driver 和 CUDA 的安装以及共享存储的挂载与节点和系统版本有关,请自行完成安装,本教程不进行介绍。
如果是多节点训练,请先将共享存储挂载到每个节点的 /storage
目录上,后续下载的内容都将放在这个目录下,并且 AReaL 容器也会将该目录挂载到容器的 /storage
,以便训练时访问。
一键搭建环境并启动训练
本节提供一个一键安装脚本,自动完成节点的环境配置工作:
- 安装 Docker,Git LFS,NVIDIA Container Toolkit
- 在每个节点上拉取 AReaL 镜像
- 下载 AReaL 代码,模型,数据集
- 搭建 Ray 集群
- 【可选】在 Ray 集群中启动一个训练任务
请选择任意一个节点执行如下操作:
mkdir -p /storage/codes
cd /storage/codes/
git clone https://github.com/inclusionAI/AReaL.git
cd /storage/codes/AReaL
python ./examples/env/setup_env_and_start_train.py setup --private_key_file /path/to/ssh_key --ssh_port 22 --username root --hostnames NODE_IP_1 NODE_IP_2 NODE_IP_3 NODE_IP_4 --train_param 1.5B_n1
setup_env_and_start_train.py setup
参数说明:
private_key_file
:SSH 私钥文件,用于连接节点ssh_port
:SSH 端口username
:SSH 用户名hostnames
:IP 列表,用空格分割。可以是 1/4/16 个节点 IPtrain_param
:【可选】训练参数,用于在完成环境搭建后直接启动一个训练任务。可选值为1.5B_n1
,1.5B_n4
,1.5B_n16
,7B_n4
,7B_n16
如果因为环境差异,无法运行本节中的脚本或运行出现错误,也可以按照本教程后续章节的内容手动完成环境配置和启动训练。
环境配置
由于使用了共享存储,下载操作只需要在一个节点上完成。
代码
将 AReaL 项目代码克隆到 /storage/codes
中:
mkdir -p /storage/codes
cd /storage/codes/
git clone https://github.com/inclusionAI/AReaL.git
数据集
我们提供了用于训练的数据集,请下载数据集并放置在 /storage/datasets/
mkdir -p /storage/datasets/
cd /storage/datasets/
wget https://huggingface.co/datasets/inclusionAI/AReaL-RL-Data/resolve/main/data/boba_106k_0319.jsonl?download=true
wget https://huggingface.co/datasets/inclusionAI/AReaL-RL-Data/resolve/main/data/orz-zero_56k_0319.jsonl?download=true
模型
我们基于开源模型进行训练,该模型可以从 HuggingFace Hub 直接下载(请确保已经安装了 Git LFS):
mkdir -p /storage/models
cd /storage/models
GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
cd DeepSeek-R1-Distill-Qwen-7B
git lfs pull
你也可以在安装 PyPI 和 huggingface_hub 后利用 huggingface CLI 进行下载,具体请参考官方文档
启动 Ray 集群
在执行这一步之前,请先拉取 AReaL 环境镜像,这个镜像中已经包含了 Ray 相关的组件。
在第一个节点上执行如下命令启动 Ray Head:
docker run -d --name r1-ray-head --privileged --gpus all --network host --shm-size 700g -v /storage:/storage ghcr.io/inclusionai/areal-runtime:v0.2.0 /bin/bash -c "ray start --head --port=6379 && tail -f /dev/null"
在除了第一个节点以外的每个节点上执行如下命令启动 Ray Worker(如果只有一个节点,这一步就不用执行了):
# RAY_HEAD_IP 是第一个节点的 IP
RAY_HEAD_IP=xxx.xxx.xxx.xxx
docker run -d --name r1-ray-worker --privileged --gpus all --network host --shm-size 700g -v /storage:/storage ghcr.io/inclusionai/areal-runtime:v0.2.0 /bin/bash -c "ray start --address=$RAY_HEAD_IP:6379 && tail -f /dev/null"
全部启动完成后,在第一个节点上通过 docker exec 进入容器,查看 Ray 集群的状态:
docker exec -it r1-ray-head bash
ray status
可以看到 Ray 的资源情况,输出如下(这是一个 16 节点 128 卡的集群,根据你的节点数量,这里的输出会有所不同):
======== Autoscaler status: 2025-02-22 14:08:51.061250 ========
Node status
---------------------------------------------------------------
Active:
1 node_d5634ae61bfe6732d957811bed65c8a39f13ece07e0326f941acbc4e
1 node_23b0c08045c9a39bc4c454cae298ee531d9a474215ac5e77a5b01e74
1 node_bc1016320658e92645f29cecb8aaf51c0b7e01a44e8ac9c814dfee59
1 node_4e7d15e9cee9ee0da5d65e45f1e346228c52bc0c557511c6eeab40dc
1 node_c5bcf15e28a00515be5d2a7e8e33d71f0f57cdfaf1003db9e0c74788
1 node_ec3f6ee8f6fdf3a5392bb4dac244668da75d094e084dcbb520ce2525
1 node_dc2f1eef88126ae4ac7902574714af9ab74b78ba037217e73e063639
1 node_a4728608c1fda187dc33bb24e831c42fe5c8a582ad428b6e595933bc
1 node_970379a3ba750ee3b13e31612b6a6b758d50bd4943555b2a13d1bd61
1 node_bf6b658bea9e437fcb642a2d881425662a689d668c92fe1545899b36
1 node_2c69511f410d9360f1d05893fde2c97dd32240e0315afea9b2d286a3
1 node_e4c90c17cc48ad469d123041d3302dcff1f7a82a4805279300812b19
1 node_3f772cbffb206c30b6ccedade83789d78397804bab874ee59563cb96
1 node_429bd5115b5590b612590bb455f2d3ed4f77055d746a184baf807655
1 node_75071820f2c16dc51fa271316b72cd45335ec877c06450d292ab7d54
1 node_6f4323f9038248d82b91321e2c4ca5fa99e65efa2d976c0b896a8964
Pending:
(no pending nodes)
Recent failures:
(no failures)
Resources
---------------------------------------------------------------
Usage:
0.0/2128.0 CPU
0.0/128.0 GPU
0B/21.08TiB memory
0B/2.91TiB object_store_memory
Demands:
(no resource demands)
RL训练
在进行分布式训练之前,请确保已经启动了 Ray 集群,并且集群状态正常。 然后在第一个节点(Ray Head 所在节点),进入容器:
docker exec -it r1-ray-head bash
cd /storage/codes/AReaL
选择匹配硬件环境的一个配置运行即可:
python3 -m realhf.apps.quickstart ppo-math --config ./examples/configs/7B-distill/ppo-7B-distill-gpus-128.yaml
启动后,在终端可以看到启动日志:
╭─────────────────────────────────────────────────╮
│ Setting PPOMATHConfig with the Following Values │
╰─────────────────────────────────────────────────╯
───────────────────────── Current Configuration Begin ──────────────────────────
actor (ModelTrainEvalConfig)
actor.type (ModelFamily)
actor.type._class (str) - qwen2
actor.type.size (int) - 7
actor.type.is_critic (bool) - False
...
────────────────────────── Current Configuration End ───────────────────────────
20250222-10:26:34.877 quickstart INFO: Running ppo-math experiment.
20250222-10:44:15.581 quickstart INFO: Logs will be dumped to /storage/ray/experiments/logs/root/ppo-7B-distill-gpus-128/512x16
20250222-10:44:15.581 quickstart INFO: Model checkpoints will be saved to /storage/ray/experiments/checkpoints/root/ppo-7B-distill-gpus-128/512x16
20250222-10:26:36.408 quickstart INFO: Launching experiments with RAY...
如果运行过程中出现错误(比如出现 Error 关键字),请参考Troubleshooting解决。
Commandline Options
python3 -m realhf.apps.quickstart ppo-math --help
其中重要的参数的说明如下:
-
mode:总是为 ray,参考本教程进行训练时不要改成其他值。
-
{actor|critic|ref}.path:模型的路径
-
dataset.path:数据集 jsonl 文件的路径
-
external_configs.cluster_config:设置 cluster_config 的配置,比如 fileroot 是存放训练输出的根目录。
-
n_nodes:节点数量
-
n_gpus_per_node:每个节点的 GPU 数量
-
allocation_mode:实验中模型的 GPU 分配和 3D 并行策略,推荐的策略有以下形式:
sglang.d${DP1}m${TP1}p${PP1}+d${DP2}m${TP2}p${PP2}
: 分别配置 SGLang 生成和训练的并行策略,生成和训练分离,使用两部分不同的 GPU。二者所用的GPU数量相加要等于总的 GPU 数量,即 DP1xTP1xPP1+DP2xTP2xPP2=#GPUs。
-
exp_ctrl.total_train_epochs:训练的 epoch 数量(即迭代整个数据集的次数)
-
exp_ctrl.save_freq_{epochs|steps|secs}:保存持久化存储模型参数的频率,如果设成 null 会不保存模型
-
exp_ctrl.ckpt_freq_{epochs|steps|secs}:保存临时参数用于重启的频率
-
dataset.train_bs_n_seqs:训练的批量大小,即每次训练需要采样的 prompt 数量
-
group_size:每个 prompt 需要采样的答案数量
-
{actor_train|ref_inf}.mb_spec.max_tokens_per_mb:reference模型推理和actor模型训练每次forward/backward数据中最大的token数量,可以减小以避免OOM错误。这些数据会累积梯度进行一次参数更新。
-
ppo.ppo_n_minibatches:每次PPO更新中会把所有数据划分成多少份以此进行loss计算和参数更新。
-
ppo.gen.max_new_tokens:每条prompt生成的最大token数,默认训练脚本中为16k。
-
ppo.gen.min_new_tokens:每条prompt生成的最小token数,默认为0。
过程观测
这里以 16 节点的运行日志为例(1 节点和 4 节点也一样),说明几个观察训练进度和效果的方法。
查看训练进度
搜索日志中的 Epoch 关键字,查看总的 Epoch 数量和 Step 数量:
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-11:11:56.997 master worker INFO: Epoch 1/1 step 1/19 (global step 1) finishes. Average #tokens per batch is 111847. #End to end# execution time: *2124.429*s. Total time consumption: 2283.862s.
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-11:52:02.719 master worker INFO: Epoch 1/1 step 2/19 (global step 2) finishes. Average #tokens per batch is 111847. #End to end# execution time: *2405.716*s. Total time consumption: 4689.584s.
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-12:27:25.084 master worker INFO: Epoch 1/1 step 3/19 (global step 3) finishes. Average #tokens per batch is 111847. #End to end# execution time: *2122.318*s. Total time consumption: 6811.949s. Estimated remaining time: 33957.093s.
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-13:05:58.246 master worker INFO: Epoch 1/1 step 4/19 (global step 4) finishes. Average #tokens per batch is 111847. #End to end# execution time: *2313.134*s. Total time consumption: 9125.111s. Estimated remaining time: 33265.891s.
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-13:44:14.349 master worker INFO: Epoch 1/1 step 5/19 (global step 5) finishes. Average #tokens per batch is 111847. #End to end# execution time: *2296.076*s. Total time consumption: 11421.214s. Estimated remaining time: 31413.800s.
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-14:22:33.864 master worker INFO: Epoch 1/1 step 6/19 (global step 6) finishes. Average #tokens per batch is 111847. #End to end# execution time: *2299.448*s. Total time consumption: 13720.729s. Estimated remaining time: 29350.673s.
出现了 6 条日志信息,以最后一条信息的内容说明各个字段的含义:
Epoch 1/1
:表示总共需要训练 1 个 Epochs,当前在训练第 1 个。这里作为例子总共只训练 1 个 Epoch,正常训练应该是 10 个 Epochs 或者更多。step 6/19
:表示当前 Epoch 有 19 个 Steps,当前在训练第 6 个global step 6
: 表示当前 Step 在所有 Epochs 的 Steps 里的序号#End to end# execution time: *2299.448*s
:表示当前 Step 训练耗费了 2299.448 秒Total time consumption: 13720.729s
:从训练启动开始一共耗费了 13720.729 秒Estimated remaining time: 29350.673s
:预计完成训练还需要 29350.673 秒
查看训练的效果
搜索日志中的 task_reward
关键字
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-11:11:56.991 master worker INFO: RPC name actor_train returns {'ppo_approx_kl': -2.2640759198111482e-05, 'actor_loss': 1.1128166761409375e-06, 'actor_clip_ratio': 2.1122002635820536e-07, 'importance_weight': 1.0000014305114746, 'task_reward': -0.2996826171875, 'kl_reward': -2.27004832709099e-07, 'final_reward': -0.30145370960235596, 'advantage': 0.003593671601265669, 'avg_seq_len': 7907.8955078125, 'avg_prompt_len': 105.845703125, 'n_tokens': 127828786.0, 'n_valid_tokens': 127828786.0, 'n_seqs': 16384.0, 'no_eos_ratio': 0.122802734375, 'disable_value': 1.0, 'mask_no_eos_with_zero': 0.0}
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-11:52:02.712 master worker INFO: RPC name actor_train returns {'ppo_approx_kl': -2.493159263394773e-05, 'actor_loss': -3.846728588996484e-07, 'actor_clip_ratio': 3.16789424914532e-07, 'importance_weight': 0.9999996423721313, 'task_reward': -0.6793212890625, 'kl_reward': -2.536311853873485e-07, 'final_reward': -0.6813737154006958, 'advantage': 0.004844569601118565, 'avg_seq_len': 8203.9453125, 'avg_prompt_len': 111.892578125, 'n_tokens': 132580185.0, 'n_valid_tokens': 132580185.0, 'n_seqs': 16384.0, 'no_eos_ratio': 0.13812255859375, 'disable_value': 1.0, 'mask_no_eos_with_zero': 0.0}
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-12:27:25.077 master worker INFO: RPC name actor_train returns {'ppo_approx_kl': -2.572356243035756e-05, 'actor_loss': -5.036404786551429e-07, 'actor_clip_ratio': 1.8960582792715286e-07, 'importance_weight': 0.9999992251396179, 'task_reward': -0.6280517578125, 'kl_reward': -2.988609537624143e-07, 'final_reward': -0.6303607225418091, 'advantage': 0.004505862481892109, 'avg_seq_len': 7834.6328125, 'avg_prompt_len': 108.900390625, 'n_tokens': 126578395.0, 'n_valid_tokens': 126578395.0, 'n_seqs': 16384.0, 'no_eos_ratio': 0.11761474609375, 'disable_value': 1.0, 'mask_no_eos_with_zero': 0.0}
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-13:05:58.239 master worker INFO: RPC name actor_train returns {'ppo_approx_kl': -2.4861981728463434e-05, 'actor_loss': 1.3935685672095133e-07, 'actor_clip_ratio': 3.02603467616791e-07, 'importance_weight': 0.9999998807907104, 'task_reward': -0.78857421875, 'kl_reward': -3.672174671009998e-07, 'final_reward': -0.791388750076294, 'advantage': 0.005053278990089893, 'avg_seq_len': 7773.39404296875, 'avg_prompt_len': 108.7890625, 'n_tokens': 125576883.0, 'n_valid_tokens': 125576883.0, 'n_seqs': 16384.0, 'no_eos_ratio': 0.117919921875, 'disable_value': 1.0, 'mask_no_eos_with_zero': 0.0}
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-13:44:14.342 master worker INFO: RPC name actor_train returns {'ppo_approx_kl': -2.516058702894952e-05, 'actor_loss': -7.665488510610885e-07, 'actor_clip_ratio': 1.9505058901359007e-07, 'importance_weight': 0.9999997615814209, 'task_reward': -0.6158447265625, 'kl_reward': -4.6867208425283025e-07, 'final_reward': -0.6195111274719238, 'advantage': 0.004475570283830166, 'avg_seq_len': 7928.50830078125, 'avg_prompt_len': 105.517578125, 'n_tokens': 128171874.0, 'n_valid_tokens': 128171874.0, 'n_seqs': 16384.0, 'no_eos_ratio': 0.12353515625, 'disable_value': 1.0, 'mask_no_eos_with_zero': 0.0}
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-14:22:33.857 master worker INFO: RPC name actor_train returns {'ppo_approx_kl': -2.4821250917739235e-05, 'actor_loss': -3.922649227661168e-07, 'actor_clip_ratio': 3.323623900541861e-07, 'importance_weight': 1.0000001192092896, 'task_reward': -0.7025146484375, 'kl_reward': -5.863367960046162e-07, 'final_reward': -0.7071446776390076, 'advantage': 0.004277692176401615, 'avg_seq_len': 8002.4873046875, 'avg_prompt_len': 105.951171875, 'n_tokens': 129376851.0, 'n_valid_tokens': 129376851.0, 'n_seqs': 16384.0, 'no_eos_ratio': 0.12286376953125, 'disable_value': 1.0, 'mask_no_eos_with_zero': 0.0}
以最后一条说明其中几个重点字段的含义:
task_reward
:这个step中采样的所有答案的平均奖励值,训练稳步进行的话这个值会持续上升,最终维持不变importance_weight
: PPO loss中重要性采样比率在所有token上的平均值,通常接近1。actor_clip_ratio
: PPO loss中被clip掉的token占所有token的比率,通常小于0.1。actor_loss
: PPO loss,不会随着训练过程有明显的上升或下降趋势,不应作为模型表现的参考。avg_seq_len
: 这一步中采样的所有序列(即提示词和答案相加)的平均长度。在完整的多阶段训练中,这个值会先下降再上升。no_eos_ratio
: 这一步中采样的所有答案因为超出最大生成长度被截断的比率。这个值上升也代表了答案的平均长度在上升。
评估
评估流程
评估代码包含在仓库的evaluation
文件夹中。按照以上的教程,训练得到的checkpoint会保存在/storage/ray/experiments/checkpoints/root/
路径下,例如/storage/ray/experiments/checkpoints/root/ppo-zero-distill-7B-n16/1024x16-n16/actor/epoch1epochstep20globalstep20/
。
启动一个新的容器用于运行评估脚本(评估需要更新部分 python 库,请不要在训练容器中进行):
docker run -d --name r1-eval --privileged --gpus all --network host --shm-size 700g -v /storage:/storage ghcr.io/inclusionai/areal-runtime:v0.2.0 /bin/bash -c "tail -f /dev/null"
docker exec -it r1-eval bash
在docker容器内部运行以下脚本进行评估:
cd /storage/codes/AReaL/evaluation
cd latex2sympy
pip install -e .
cd ..
pip install -r requirements.txt
pip install vllm --no-build-isolation
pip install transformers==4.47.0
pip install prettytable timeout_decorator
mkdir /storage/ray/eval_output/
nohup python eval_and_aggregate.py \
--model_path /storage/ray/experiments/checkpoints/root/ppo-zero-distill-7B-n16/1024x16-n16/actor/epoch1epochstep20globalstep20/ \
--output_path /storage/ray/eval_output/ \
--data_names "math_500,aime24,amc23" \
--max_gen_tokens 32768 &> /storage/ray/eval_output/eval_and_aggregate_parallel.log &
--model_path
:模型参数的保存路径--output_path
:评估过程中生成的答案和日志文件路径--data_names
: 可以指定评测某个数据,多个数据集用逗号隔开,默认为 math_500, aime24, amc23--max_gen_tokens
:最长的答案生成长度,默认值 32768
评估结果
评估脚本运行完后会在 /storage/ray/eval_output/eval_and_aggregate_parallel.log 日志文件输出一个表格,例如:
+----------+---------------+---------------+---------------+------------+---------------+--------+---------+
| dataset | num_questions | greedy_length | sample_length | greedy_acc | sample_pass@1 | pass@8 | pass@16 |
+----------+---------------+---------------+---------------+------------+---------------+--------+---------+
| math_500 | 500 | 6757.4 | 4139.5 | 84.4 | 92.7 | 97.3 | 97.7 |
| aime24 | 30 | 19328.0 | 13663.5 | 50.0 | 50.4 | 77.3 | 80.0 |
| amc23 | 40 | 8850.0 | 6526.2 | 80.0 | 90.5 | 96.8 | 98.8 |
+----------+---------------+---------------+---------------+------------+---------------+--------+---------+
{greedy|sample}_length
: 在greedy或随机采样策略下生成的平均答案长度greedy_acc
:在greedy采样下的平均准确率sample_pass@{k}
:在随机采样下平均每k个答案产生正确答案的概率
额外说明
关键参数
- 我们提供的评估脚本默认采样32次取平均值,采样温度值为0.6
- 我们发现vLLM的
enforce_eager
参数很大程度影响评估性能,当enforce_eager=True
时我们才能够复现先前工作汇报的模型表现,否则评估结果会低于先前工作汇报的结果,因此我们会在执行eval_and_aggregate_parallel.py
时将enforce_eager
强制开启。
由于以上原因,评估过程通常会消耗较长时间。
运行时间
评估的运行时间取决于最长生成长度、数据集的题目数量和模型大小等等。在1台8*H100机器上,7B模型,数据集为math_500,aime24,amc23
,生成长度为32768,评估脚本运行时间为 5 个小时。
Troubleshooting
如果以下内容没有解答你的问题,欢迎在 GitHub Issue 中进行提问。
自动恢复
当设置了 recover_mode=auto
并且训练配置和之前相同,AReaL 会尝试找到之前生成的 checkpoints 并且从这个 checkpoints 恢复训练。
如果自动恢复失败,有这些可能性:
- 训练配置里的
experiment_name
和trial_name
与之前的不一样 - Batch Size(参数里的
dataset.train_bs_n_seqs
),Group Size(参数里的group_size
),节点数(参数里的n_nodes
)三个值发生了变化 - 之前的训练没有创建过 recover checkpoint 。默认的 recover checkpoint 规则有 2 个:
- 从第 2 个 step 完成后才生成 recover checkpoint
- 一个 step 训练完成,且距离上次 recover checkpoint 时间超过 600s,则生成一个新的 recover checkpoint。这个参数在
./examples/configs/*/*.yaml
文件里,参数名为 :exp_ctrl.ckpt_freq_secs=600
。
可以通过搜索 Dumped recover
确认是否生成过 recover checkpoint
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-11:52:02.760 master worker INFO: Dumped recover info to file.
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-12:27:25.105 master worker INFO: Dumped recover info to file.
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-13:05:58.264 master worker INFO: Dumped recover info to file.
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-13:44:14.411 master worker INFO: Dumped recover info to file.
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-14:22:33.883 master worker INFO: Dumped recover info to file.
(master_worker/0 pid=96390, ip=xxx.xxx.xxx.xxx) 20250222-14:59:44.925 master worker INFO: Dumped recover info to file.
一系列OutOfMemory错误
我们提供的脚本已经尽最大努力避免了OOM错误的发生,但是OOM问题仍然会随着训练进行,在内存碎片增加和生成序列长度越来越长时偶尔发生。虽然这些问题通常可以通过自动重启解决,当重启频繁时,用户还可以尝试以下针对性的解决方式。
torch.cuda.CudaOutOfMemoryError
解决这个问题的关键是定位错误发生的阶段。
- 如果发生在初始化阶段(在进入到actor_gen之前):
- 检查当前GPU上是否存在残留进程。在分布式场景下,可以通过重启ray cluster解决;在单机场景下,可以通过pkill解决。
- 该错误通常不会发生在actor_gen阶段。
- 如果发生在ref_inf或actor_train阶段
- 改变相应计算任务的microbatch大小,例如
actor_train.mb_spec.max_tokens_per_mb=20480
,这个参数代表每次模型forward/backward的数据最多只会包含20480个token,这个值最小可以设为生成序列的最长长度(包括prompt) - 改变模型的并行策略,即
allocation_mode
,可以尝试减少数据并行的大小,增加张量或流水线并行的大小。
- 改变相应计算任务的microbatch大小,例如
CUDA error: out of memory
这个问题可能会发生在vLLM初始化CPU KV cache时,表示每台机器的内存不够了。可以减小actor.vllm.swap_space
解决。
RuntimeError: Aborted due to the lack of CPU swap space.
问题的原因是序列长、对KV cache需求大,在GPU显存不够时KV cache会被卸载到内存,而内存中设置的swap space不够。这个问题和Preemption的报错紧密相关。解决方案是增加actor.vllm.swap_space
,如果同样的错误出现,请减少actor.vllm.max_num_seqs
并参考vLLM官方文档。
CUDA error: an illegal memory access was encountered
通常会在vLLM生成阶段出现,同样是显存不足的一种表现。解决方案包括:
- 减小训练batch size或者每个prompt生成的答案数量,但减小后会降低样本效率、延长训练时间
- 将vLLM的attention backend换成xformers