已合并
【Ray GRPO】添加GRPO ST用例,并补充readme,fix config bug #2175
一只想当程序员的Z创建于 2025年1月23日
【Ray GRPO】添加GRPO ST用例,并补充readme,fix config bug #2175
已合并
从refs/pull/2175/head合入到master
共 6 个文件变更+240-2
| @@ -53,8 +53,6 @@ actor_rollout_ref: | |||
| 53 | data_path: ./dataset/descriptiveness/descriptiveness | 53 | data_path: ./dataset/descriptiveness/descriptiveness |
| 54 | split: 100,0,0 | 54 | split: 100,0,0 |
| 55 | n_samples_per_prompt: 4 | 55 | n_samples_per_prompt: 4 |
| 56 | - kl_type: fixed | ||
| 57 | - kl_coef: 0.05 | ||
| 58 | 56 | ||
| 59 | ref: | 57 | ref: |
| 60 | model: llama32-1b | 58 | model: llama32-1b |
| @@ -75,6 +73,9 @@ algorithm: | |||
| 75 | lam: 0.95 | 73 | lam: 0.95 |
| 76 | adv_estimator: group_norm | 74 | adv_estimator: group_norm |
| 77 | kl_penalty: kl | 75 | kl_penalty: kl |
| 76 | + kl_ctrl: | ||
| 77 | + type: fixed | ||
| 78 | + kl_coef: 0.05 | ||
| 78 | missing_eos_penalty: 0.0 | 79 | missing_eos_penalty: 0.0 |
| 79 | 80 | ||
| 80 | resource_pool: | 81 | resource_pool: |
| @@ -0,0 +1,122 @@ | |||
| 1 | +# 后训练方法 Ray GRPO | ||
| 2 | + | ||
| 3 | +[Group Relative Policy Optimization (GRPO) ](https://arxiv.org/pdf/2402.03300)是 DeepSeek V2中提出的训练方法,它移除了 PPO 中对 Critic模型的依赖,而是使用对同一问题产生的多个采样输出的平均值作为奖励,从而大大减少了显存占用。 | ||
| 4 | + | ||
| 5 | +GRPO方法中包含了三个模型:Actor,Reference,Reward。其中Actor/Reference模型是经过预训练和指令微调(Supervised Fine-Tuning,SFT)得到的大语言模型,Reward是训练得到的奖励模型。GRPO 的训练目标是使得 Actor 模型的回答可以更加符合人类偏好。 | ||
| 6 | + | ||
| 7 | +# 使用说明 | ||
| 8 | + | ||
| 9 | +## 环境配置 | ||
| 10 | + | ||
| 11 | +配置MindSpeed-LLM基础环境: 参考[安装指南](./install_guide.md) | ||
| 12 | + | ||
| 13 | +## 数据预处理 | ||
| 14 | + | ||
| 15 | +数据集转换参考脚本:MindSpeed-LLM/examples/mcore/llama3/data_convert_llama3_ppo.sh | ||
| 16 | +以 [descriptiveness 数据集](https://huggingface.co/datasets/trl-internal-testing/descriptiveness-sentiment-trl-style/tree/main/data) 为例。 | ||
| 17 | + | ||
| 18 | +```bash | ||
| 19 | +source /usr/local/Ascend/ascend-toolkit/set_env.sh | ||
| 20 | +mkdir ./dataset/llama3-hf/ | ||
| 21 | + | ||
| 22 | +python ./preprocess_data.py \ | ||
| 23 | + --input ./dataset/descriptiveness-00000-of-00001.parquet \ | ||
| 24 | + --tokenizer-name-or-path ./model_from_hf/llama3-hf/ \ | ||
| 25 | + --output-prefix ./dataset/llama3-hf/descriptiveness \ | ||
| 26 | + --workers 16 \ | ||
| 27 | + --log-interval 1000 \ | ||
| 28 | + --tokenizer-type PretrainedFromHF \ | ||
| 29 | + --handler-name PPOAlpacaStyleInstructionHandler \ | ||
| 30 | + --prompt-type llama3 \ | ||
| 31 | + --map-keys '{"prompt":"prompt", "query":"", "response": "prompt", "system":""}' | ||
| 32 | +``` | ||
| 33 | + | ||
| 34 | +## 模型权重转换 | ||
| 35 | + | ||
| 36 | +根据 GRPO 算法要求,Actor 和 Reference 模型应该使用 SFT 微调后的模型进行初始化,Reward 模型应该使用奖励模型训练后的模型进行初始化。GRPO 算法模型权重均使用Megatron-mcore格式,其他格式的权重需要进行模型权重转换,具体可参考[权重转换](./checkpoint.md)。 | ||
| 37 | + | ||
| 38 | +## 启动方式 | ||
| 39 | + | ||
| 40 | +### 单机 | ||
| 41 | + | ||
| 42 | +通过 --config-name 传递选取的 config 文件名(不添加.yaml后缀),可以通过下列命令直接启动训练(Llama32 1B 模型可单机运行)。 | ||
| 43 | +目前已支持的配置文件放置在 configs/rlxf/ 文件夹下。配置文件的具体说明见下文。 | ||
| 44 | + | ||
| 45 | +```bash | ||
| 46 | +python ray_gpt.py --config-name grpo_trainer_llama32_1b | ||
| 47 | +``` | ||
| 48 | + | ||
| 49 | +### 多机 | ||
| 50 | + | ||
| 51 | +多机运行程序时,需要首先进入对应目录,并激活conda或docker环境: | ||
| 52 | + | ||
| 53 | +```bash | ||
| 54 | +cd MindSpeed-LLM | ||
| 55 | +conda activate xxx | ||
| 56 | +``` | ||
| 57 | + | ||
| 58 | +然后,在主节点上启动 Ray 集群: | ||
| 59 | + | ||
| 60 | +```bash | ||
| 61 | +# 创建一个集群,端口6344,dashboard端口8260,有8个NPU | ||
| 62 | +ray start --head --port 6344 --dashboard-host=0.0.0.0 --dashboard-port=8260 --resources='{"NPU": 8}' | ||
| 63 | +``` | ||
| 64 | + | ||
| 65 | +随后,在其他节点加入主节点的集群 | ||
| 66 | + | ||
| 67 | +```bash | ||
| 68 | +# IP_ADDRESS 处填写主节点 IP 地址 | ||
| 69 | +ray start --address="IP_ADDRESS:6344" --resources='{"NPU": 8}' | ||
| 70 | +``` | ||
| 71 | + | ||
| 72 | +在完成 Ray 集群构建后,在主节点启动运行程序即可(Llama3 8B 模型可双机运行) | ||
| 73 | + | ||
| 74 | +```bash | ||
| 75 | +python ray_gpt.py --config-name grpo_trainer_llama3_8b | ||
| 76 | +``` | ||
| 77 | + | ||
| 78 | +## 配置文件 | ||
| 79 | + | ||
| 80 | +由于 GRPO 训练过程中涉及 3 个模型,通过将模型参数和训练配置解耦的层级化参数配置,来简化 GRPO 训练的参数配置过程。RLXF 训练涉及到的所有配置文件均存储在 configs/rlxf 路径下,其中 model 文件夹下存储了模型结构相关的配置文件,GRPO训练相关的模型参数文件以grpo_{模型名}.yaml方式命名。 | ||
| 81 | + | ||
| 82 | +在每个 grpo_trainer 配置文件中,需要包含defaults,training,resource_pool,algorithm等字段,以及 GRPO 训练过程中涉及到的 3 个角色 actor,reward,ref的配置。其中: | ||
| 83 | + | ||
| 84 | +1. defaults 负责引入模型配置文件,在 defaults 中应列举本配置文件中所需要用到的所有模型配置,模型配置可以在下方3个角色的具体配置中通过 model 字段进行选择。 | ||
| 85 | +2. training 字段设置的参数为所有 3 个角色通用的默认参数,这些参数可以在下方进一步被角色的单独配置所覆盖。 | ||
| 86 | +3. resource_pool 字段指定了各个角色所需的 NPU 资源数量。 | ||
| 87 | +4. actor,reward,ref 字段分别指定了GRPO算法中三个角色训练相关的参数配置。 | ||
| 88 | + | ||
| 89 | +## 参数解析 | ||
| 90 | + | ||
| 91 | +相较于普通模型训练,GRPO增加一些特殊参数: | ||
| 92 | + | ||
| 93 | +### `training:` | ||
| 94 | + | ||
| 95 | +* `stage`:用于指定训练算法,使用 Ray GRPO 训练须设置为`ray_grpo`; | ||
| 96 | + | ||
| 97 | +### `actor_rollout:` | ||
| 98 | + | ||
| 99 | +* `do_sample`:控制 Actor 模型进行推理时是否采样,默认为 False,GRPO 需要设置为True ; | ||
| 100 | +* `ppo_mini_batch_size`:Actor 模型的 mini_batch_size,默认为1; | ||
| 101 | +* `max_prompt_length`:GRPO 训练中最大 prompt 长度,默认为512; | ||
| 102 | +* `num_samples_per_step`:Actor 推理时每个step的推理样本数量,默认为1; | ||
| 103 | +* `ppo_epochs`:Actor 训练对同一批经验数据的重复次数,默认为1; | ||
| 104 | +* `clip_ratio`:Actor模型训练计算损失函数时的clip比例,默认为0.2; | ||
| 105 | +* `shuffle_minibatch`:Actor 训练时是否对 minibatch 进行 shuffle,默认为 False; | ||
| 106 | +* `num_gpus_for_train` :Actor 模型分配给训练部分的显卡数量; | ||
| 107 | +* `num_gpus_for_infer` :Actor 模型分配给推理部分的显卡数量; | ||
| 108 | +* `missing_eos_penalty`:缺少序列结束符EOS时的惩罚系数; | ||
| 109 | +* `n_samples_per_prompt`:每条prompt的重用次数,代表GRPO训练流程里每个Group的数据量,默认为1; | ||
| 110 | + | ||
| 111 | +### `resource_pool:` | ||
| 112 | + | ||
| 113 | +* `actor_rollout`:给 Actor 模型训练和推理总共分配的显卡数量; | ||
| 114 | +* `ref`:给 Reference 模型分配的显卡数量; | ||
| 115 | +* `reward`:给 Reward 模型分配的显卡数量; | ||
| 116 | + | ||
| 117 | +# 精度对比 | ||
| 118 | + | ||
| 119 | +我们与强化学习开源仓库 [OpenRLHF](https://github.com/OpenRLHF/OpenRLHF) 进行了精度对比,来辅助验证算法实现的正确性。因为 GRPO group_norm的特性需求,推理状态do sample 设置为 True,为了与基准方法进行精度对齐,在 Actor 推理时固定 responses 方式进行精度对齐的实验。可以看到,固定 responses 后 loss 能够较好地实现对齐。 | ||
| 120 | + | ||
| 121 | + | ||
| 122 | + | ||
| @@ -0,0 +1,23 @@ | |||
| 1 | +{ | ||
| 2 | + "lm loss": [ | ||
| 3 | + 0.9115, | ||
| 4 | + 0.8044, | ||
| 5 | + 0.8649, | ||
| 6 | + 0.8988, | ||
| 7 | + 0.8486, | ||
| 8 | + 0.8444, | ||
| 9 | + 0.9101, | ||
| 10 | + 0.8345, | ||
| 11 | + 0.8460, | ||
| 12 | + 0.8260, | ||
| 13 | + 0.8888, | ||
| 14 | + 0.8228, | ||
| 15 | + 0.8613, | ||
| 16 | + 0.8975, | ||
| 17 | + 0.8895 | ||
| 18 | + ], | ||
| 19 | + "throughput": [ | ||
| 20 | + ], | ||
| 21 | + "memo info": [ | ||
| 22 | + ] | ||
| 23 | +} | ||
| @@ -0,0 +1,83 @@ | |||
| 1 | +defaults: | ||
| 2 | + - model: | ||
| 3 | + - llama32-1b | ||
| 4 | + | ||
| 5 | +training: | ||
| 6 | + global_batch_size: 4 | ||
| 7 | + seq_length: 512 | ||
| 8 | + tokenizer_type: PretrainedFromHF | ||
| 9 | + tokenizer_name_or_path: /data/ppo/llama-3.2-1b-instruct/ | ||
| 10 | + train_iters: 15 | ||
| 11 | + distributed_backend: nccl | ||
| 12 | + no_shared_storage: true | ||
| 13 | + save_interval: 10000 | ||
| 14 | + no_load_optim: true | ||
| 15 | + no_load_rng: true | ||
| 16 | + bf16: true | ||
| 17 | + is_instruction_dataset: true | ||
| 18 | + variable_seq_lengths: true | ||
| 19 | + no_shuffle: true | ||
| 20 | + stage: ray_grpo | ||
| 21 | + sequence_parallel: False | ||
| 22 | + | ||
| 23 | +actor_rollout_ref: | ||
| 24 | + actor_rollout: | ||
| 25 | + model: llama32-1b | ||
| 26 | + do_sample: true | ||
| 27 | + micro_batch_size: 1 | ||
| 28 | + ppo_mini_batch_size: 1 | ||
| 29 | + num_samples_per_step: 1 | ||
| 30 | + max_prompt_length: 256 | ||
| 31 | + ppo_epochs: 1 | ||
| 32 | + clip_ratio: 0.2 | ||
| 33 | + entropy_coeff: 0.001 | ||
| 34 | + shuffle_minibatch: false | ||
| 35 | + use_kv_cache: true | ||
| 36 | + tensor_model_parallel_size: 1 | ||
| 37 | + pipeline_model_parallel_size: 1 | ||
| 38 | + lr: 1e-7 | ||
| 39 | + lr_decay_style: constant | ||
| 40 | + min_lr: 0.0 | ||
| 41 | + weight_decay: 0.0 | ||
| 42 | + lr_warmup_fraction: 0.0 | ||
| 43 | + clip_grad: 10000.0 | ||
| 44 | + adam_beta1: 0.9 | ||
| 45 | + adam_beta2: 0.999 | ||
| 46 | + initial_loss_scale: 4096 | ||
| 47 | + finetune: true | ||
| 48 | + load: /data/ppo/llama-3.2-1b-instruct-tp1-pp1 | ||
| 49 | + save: ./ckpt | ||
| 50 | + num_gpus_for_train: 1 | ||
| 51 | + num_gpus_for_infer: 1 | ||
| 52 | + pad_to_multiple_of: 1 | ||
| 53 | + data_path: /data/ppo/llama32-ppo-trl/alpaca | ||
| 54 | + split: 100,0,0 | ||
| 55 | + n_samples_per_prompt: 4 | ||
| 56 | + ref: | ||
| 57 | + model: llama32-1b | ||
| 58 | + tensor_model_parallel_size: 1 | ||
| 59 | + pipeline_model_parallel_size: 1 | ||
| 60 | + micro_batch_size: 4 | ||
| 61 | + load: /data/ppo/llama-3.2-1b-instruct-tp1-pp1 | ||
| 62 | + | ||
| 63 | +reward: | ||
| 64 | + model: llama32-1b | ||
| 65 | + tensor_model_parallel_size: 1 | ||
| 66 | + pipeline_model_parallel_size: 1 | ||
| 67 | + micro_batch_size: 4 | ||
| 68 | + load: /data/ppo/llama-3.2-1b-rm-mcore-tp1-pp1 | ||
| 69 | + | ||
| 70 | +algorithm: | ||
| 71 | + gamma: 1.0 | ||
| 72 | + lam: 0.95 | ||
| 73 | + adv_estimator: group_norm | ||
| 74 | + kl_penalty: kl | ||
| 75 | + kl_ctrl: | ||
| 76 | + type: fixed | ||
| 77 | + kl_coef: 0.05 | ||
| 78 | + missing_eos_penalty: 0.0 | ||
| 79 | + | ||
| 80 | +resource_pool: | ||
| 81 | + actor_rollout: [2] | ||
| 82 | + ref: [1] | ||
| 83 | + reward: [1] | ||
| @@ -0,0 +1,9 @@ | |||
| 1 | +#!/bin/bash | ||
| 2 | +export CUDA_DEVICE_MAX_CONNECTIONS=1 | ||
| 3 | +export HCCL_DETERMINISTIC=True | ||
| 4 | + | ||
| 5 | + | ||
| 6 | +basepath=$(cd `dirname $0`; cd ../../../; pwd) | ||
| 7 | + | ||
| 8 | + | ||
| 9 | +python $basepath/ray_gpt.py --config-dir=$basepath/tests/st/configs --config-name=ray_grpo_full_llama32_1b_tp1pp1 | ||