如何将Llama-3接入verl?实操经验分享

如何将Llama-3接入verl?实操经验分享

1. 引言:为何选择 verl 进行 LLM 后训练

大型语言模型(LLM)在完成预训练后,通常需要通过后训练(post-training)进一步适配特定任务或行为目标。这一阶段主要包括监督微调(SFT)和强化学习人类反馈(RLHF 或其变体),是实现模型对齐的关键环节。

当前主流的 post-training 框架包括 trlLLaMA-Factoryverl。其中,verl 是由字节跳动火山引擎团队开源的一个高效、灵活且面向生产环境的强化学习训练框架,专为大模型后训练设计,并作为 HybridFlow 论文的开源实现,具备显著优势:

  • 支持多样化的 RL 算法(如 PPO、GRPO)
  • 与 PyTorch FSDP、Megatron-LM、vLLM 等现代分布式框架无缝集成
  • 提供模块化 API,易于扩展和定制
  • 具备高效的 3D-HybridEngine 实现,优化通信与内存使用
  • 原生支持 HuggingFace 模型生态

本文将重点介绍如何将 Llama-3 系列模型成功接入 verl 框架,完成基于 GRPO 的强化学习训练流程,涵盖环境配置、参数调整、自定义奖励函数及模型导出等关键步骤,提供可落地的工程实践指南。


2. 环境准备与 verl 安装验证

2.1 安装 verl 及依赖项

首先,建议从源码安装 verl,以便后续进行代码修改和调试:

git clone https://github.com/volcengine/verl && cd verl pip install -e . 

为了确保 Llama-3 能够顺利加载并运行,需安装以下关键依赖包(推荐版本):

torch==2.4.0+cu124 transformers==4.47.1 accelerate==0.33.0 peft==0.14.0 vllm==0.5.4 flash-attn==2.5.9.post1 ray==2.42.1 omegaconf==2.3.0 hydra-core==1.3.2 datasets==2.20.0 wandb==0.16.3 
注意:若使用 vLLM 进行推理加速,请提前设置环境变量:

bash export VLLM_ATTENTION_BACKEND=XFORMERS

2.2 验证安装是否成功

进入 Python 环境执行以下命令:

import verl print(verl.__version__) 

若能正常输出版本号(如 0.1.0),则说明安装成功。


3. 将 Llama-3 接入 verl 的核心配置

3.1 数据格式与 tokenizer 处理

Llama-3 使用特殊的 chat template(<|begin_of_sentence|> 等特殊 token),因此必须正确配置 tokenizer 行为。

修改 tokenizer 初始化逻辑

在 verl 中,默认 tokenizer 加载方式可能无法识别 Llama-3 的模板。建议在配置文件中显式指定:

actor_rollout_ref: model: path: meta-llama/Meta-Llama-3-8B-Instruct trust_remote_code: True override_config: {} enable_gradient_checkpointing: True use_remove_padding: False 

同时,在数据处理部分启用 chat template 自动填充:

data: chat_template: "llama-3" prompt_key: "prompt" max_prompt_length: 512 max_response_length: 1024 
若 verl 不原生支持 "llama-3" 模板,可在 verl/data/utils.py 中添加如下注册逻辑:
from transformers import AutoTokenizer def get_chat_template(tokenizer_name_or_path): if "llama-3" in tokenizer_name_or_path.lower(): return { "chat_template": "{% for message in messages %}{{'<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>'}}{% endfor %}{% if add_generation_prompt %}{{ '<|start_header_id|>assistant<|end_header_id|>\n\n' }}{% endif %}" } return None 

然后在数据加载器中动态注入该模板。

3.2 配置 GRPO 训练脚本(以 Llama-3-8B 为例)

创建 grpo_llama3.yaml 配置文件,内容如下:

data: train_files: ~/data/gsm8k/train.parquet val_files: ~/data/gsm8k/test.parquet prompt_key: prompt max_prompt_length: 512 max_response_length: 1024 train_batch_size: 1024 val_batch_size: 1312 shuffle: true actor_rollout_ref: hybrid_engine: true model: path: meta-llama/Meta-Llama-3-8B-Instruct trust_remote_code: true enable_gradient_checkpointing: true use_remove_padding: false actor: strategy: fsdp ppo_mini_batch_size: 256 ppo_micro_batch_size_per_gpu: 1 ppo_max_token_len_per_gpu: 16384 grad_clip: 1.0 clip_ratio: 0.2 entropy_coeff: 0.001 use_kl_loss: true kl_loss_coef: 0.001 kl_loss_type: low_var_kl ppo_epochs: 1 optim: lr: 5e-7 lr_warmup_steps_ratio: 0.1 warmup_style: cosine fsdp_config: wrap_policy: min_num_params: 0 param_offload: false optimizer_offload: false ref: fsdp_config: param_offload: false wrap_policy: min_num_params: 0 rollout: name: vllm temperature: 0.7 top_p: 0.95 dtype: bfloat16 gpu_memory_utilization: 0.8 enforce_eager: true free_cache_engine: true load_format: dummy_dtensor tensor_model_parallel_size: 2 max_num_batched_tokens: 8192 max_num_seqs: 1024 n: 8 # GRPO requires multiple samples per prompt enable_chunked_prefill: true critic: null # GRPO does not require critic reward_model: enable: false algorithm: gamma: 1.0 lam: 1.0 adv_estimator: grpo kl_penalty: kl kl_ctrl: type: fixed kl_coef: 0.001 trainer: total_epochs: 3 project_name: llama3-grpo-finetune experiment_name: gsm8k-v1 logger: ['console'] nnodes: 1 n_gpus_per_node: 8 default_local_dir: ./checkpoints/llama3-grpo save_freq: 100 resume_mode: auto 

4. 自定义 Reward 函数:提升训练可控性

4.1 实现 CustomRewardManager

由于 GRPO 不依赖外部 reward model,我们可以通过编写自定义奖励管理器来控制生成质量。

verl/workers/reward_manager/custom_reward.py 中新增:

from verl import DataProto import torch class LengthBonusRewardManager: """鼓励更长、结构完整的回答""" def __init__(self, tokenizer, num_examine=5) -> None: self.tokenizer = tokenizer self.num_examine = num_examine self.print_counter = 0 def __call__(self, data: DataProto): reward_tensor = torch.zeros_like(data.batch['responses'], dtype=torch.float32) for i in range(len(data)): if self.print_counter < self.num_examine: print(f"Sample {i}: Prompt and Response:") data_item = data[i] prompt_ids = data_item.batch['prompts'] response_ids = data_item.batch['responses'] valid_prompt_len = data_item.batch['attention_mask'][:prompt_ids.shape[-1]].sum().item() valid_response_len = data_item.batch['attention_mask'][prompt_ids.shape[-1]:].sum().item() prompt_str = self.tokenizer.decode(prompt_ids[-valid_prompt_len:], skip_special_tokens=True) response_str = self.tokenizer.decode(response_ids[:valid_response_len], skip_special_tokens=True) if self.print_counter < self.num_examine: print("Prompt:", prompt_str) print("Response:", response_str) self.print_counter += 1 # 奖励长度 + 结尾标点存在性 length_score = len(response_str.split()) * 0.1 # 按词数打分 ends_with_punct = 1.0 if response_str.strip()[-1] in '.?!' else 0.0 final_score = length_score + ends_with_punct reward_tensor[i, valid_response_len - 1] = final_score return reward_tensor 

并在 verl/workers/reward_manager/__init__.py 中注册:

from .custom_reward import LengthBonusRewardManager __all__ = ['NaiveRewardManager', 'LengthBonusRewardManager'] 

4.2 在配置中启用自定义 Reward

修改主配置文件中的 reward_manager 字段:

reward_manager: custom custom_reward_class: LengthBonusRewardManager 

并在 main_ppo.py 中增加导入逻辑:

if config.reward_manager == 'custom': from verl.workers.reward_manager.custom_reward import LengthBonusRewardManager reward_manager = LengthBonusRewardManager(tokenizer=tokenizer, num_examine=5) else: reward_manager = NaiveRewardManager(tokenizer=tokenizer, rm_model=None) 

5. 启动训练与常见问题解决

5.1 启动命令

set -x export VLLM_ATTENTION_BACKEND=XFORMERS CONFIG_PATH="./configs/grpo_llama3.yaml" python3 -m verl.trainer.main_ppo --config_path=$CONFIG_PATH 

5.2 常见问题与解决方案

❌ 问题1:vLLM 加载 Llama-3 报错“unknown model type”

原因:vLLM 版本过低不支持 Llama-3 架构。

解决方案:升级至 vLLM >= 0.5.4,并确认 HF 模型路径正确。

❌ 问题2:FSDP 训练时 OOM

原因:Llama-3-8B 显存占用高,batch size 设置过大。

解决方案: - 降低 ppo_micro_batch_size_per_gpu 至 1 - 开启 enable_gradient_checkpointing - 使用 bfloat16 精度 - 调整 gpu_memory_utilization: 0.7

❌ 问题3:生成结果重复或陷入循环

原因:temperature 设置过低或 top_p 过小。

建议参数

rollout: temperature: 0.7~1.0 top_p: 0.9~0.95 n: 8 # 提高多样性采样 

6. 模型保存与 HuggingFace 格式转换

6.1 检查点结构说明

verl 默认保存的是包含优化器状态的完整 checkpoint,路径结构如下:

checkpoints/ └── llama3-grpo/ └── global_step_100/ └── actor/ ├── model_world_size_8_rank_0.pt ├── model_world_size_8_rank_1.pt ... 

6.2 转换为 HuggingFace 可加载格式

使用以下脚本将 FSDP 分片权重合并为标准 HF 格式:

#!/usr/bin/env python import torch from collections import defaultdict from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer def convert_fsdp_to_hf(fsdp_ckpt_dir, hf_model_path, output_dir, step=100, world_size=8): state_dict = defaultdict(list) ckpt_path = f"{fsdp_ckpt_dir}/global_step_{step}/actor" for rank in range(world_size): file_path = f"{ckpt_path}/model_world_size_{world_size}_rank_{rank}.pt" print(f"Loading rank {rank}...") shard = torch.load(file_path) for k, v in shard.items(): state_dict[k].append(v.to_local()) merged_state_dict = {} for k, v_list in state_dict.items(): merged_state_dict[k] = torch.cat(v_list, dim=0) config = AutoConfig.from_pretrained(hf_model_path) model = AutoModelForCausalLM.from_config(config) model.load_state_dict(merged_state_dict) model.save_pretrained(output_dir, max_shard_size="10GB") tokenizer = AutoTokenizer.from_pretrained(hf_model_path) tokenizer.save_pretrained(output_dir) print(f"Model saved to {output_dir}") if __name__ == "__main__": convert_fsdp_to_hf( fsdp_ckpt_dir="./checkpoints", hf_model_path="meta-llama/Meta-Llama-3-8B-Instruct", output_dir="./hf_checkpoints/llama3-grpo-step100", step=100, world_size=8 ) 

转换完成后即可用标准方式加载:

from transformers import pipeline pipe = pipeline( "text-generation", model="./hf_checkpoints/llama3-grpo-step100", device_map="auto", torch_dtype=torch.bfloat16 ) 

7. 总结

本文系统介绍了如何将 Llama-3 系列模型成功接入 verl 框架,完成基于 GRPO 的强化学习训练全流程。主要内容包括:

  1. 环境搭建:正确安装 verl 及其依赖,特别是 vLLM 和 FlashAttention;
  2. 模型接入:通过配置文件指定 Llama-3 路径,并处理其特有的 chat template;
  3. 训练配置:合理设置 GRPO 参数,尤其是 n 采样数、KL 正则系数等;
  4. 自定义奖励:实现 CustomRewardManager 来引导模型生成更高质量响应;
  5. 问题排查:针对 OOM、生成异常等问题提供实用调参建议;
  6. 模型导出:将 verl 的分布式 checkpoint 转换为 HuggingFace 标准格式,便于部署。

通过上述实践,开发者可以充分利用 verl 的高性能与灵活性,高效完成 Llama-3 等先进大模型的对齐训练任务,为实际应用场景提供强有力的支持。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 ZEEKLOG星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Read more

百瑞互联(barrot)蓝牙,手柄,键盘,鼠标,蓝牙适配器,智能家居,蓝牙6.0。(BR8652,BR8654)

描述 BR8654A02 是北京百瑞互联(BARROT)推出的一款高度集成蓝牙 6.0 SOC 芯片,专为无线数据传输和智能互联设备打造。芯片整合了低功耗处理器、RF 收发器、多协议接口及电源管理单元,具备低功耗、适配范围广、连接稳定的特点,能满足各类蓝牙相关产品的无线通信需求,广泛适用于蓝牙 HID 设备、智能家居、遥控器、玩具、Mesh 网络及数据通信产品。 环境与封装参数 * 蓝牙 6.0 合规,连接更高效:兼容蓝牙 6.0 规范,支持 LE 1M/2M/Coded PHY 及 BR/EDR,可同时维护多链路连接(最多 4 个 BLE

OpenClaw配置飞书机器人完整指南

OpenClaw配置飞书机器人完整指南 使用openclaw channels add配置飞书机器人需完成插件安装→飞书应用创建→通道配置→事件订阅→发布应用五个核心步骤,以下是可直接执行的详细流程。 文章目录 * OpenClaw配置飞书机器人完整指南 * 一、前置准备 * 二、通道配置(openclaw channels add) * 方法1:交互式向导配置(推荐) * 方法2:非交互式命令配置(适合脚本) * 方法3:手动编辑配置文件 * 三、事件订阅与发布(关键步骤) * 四、测试与验证 * 五、常见问题排查 一、前置准备 1. 飞书开放平台创建应用(获取凭证) 1. 访问飞书开放平台:https://open.feishu.cn/app 2. 创建企业自建应用,填写名称(如"

机器人笔记——轨迹规划

机器人笔记——轨迹规划

前言 之前的文章讲过到了关节是持续运动的,雅可比矩阵正是描述关节运动与机器人末端运动映射关系的有力工具。然而有了如何映射的工具仅仅是分析机器人运动的开始,要知道空间两点间的运动轨迹是多样的,因此就产生了轨迹规划的概念。这里讲的轨迹规划可以理解为寻求最优路径的过程,下文对其展开介绍。  前序内容 * 机构自由度的计算 * 齐次变换与齐次变换矩阵的计算 * 机器人正运动学——学习笔记 * 机器人正运动学实例——PUMA560机械臂(附Matlab机器人工具箱建模代码) * 机器人逆运动学——以六自由度机器人为例(详解、易懂,附全部Matlab代码) * 双平行四边形码垛机械臂的运动学正逆解——简化方法(附完整Matlab代码、解析过程) * 机器人笔记——关于atan2与atan的区别 * 雅可比矩阵——机器人笔记(简化、易懂) 1. 什么是机器人轨迹规划? 想要解答这个问题,我们先来看什么是轨迹。 轨迹:就是机器人手臂(末端点或操作点)的位置、速度、加速度对于时间的历程; 我们在意的其实是,机器人末端轨迹对于工件的状态或相对关系,就像下面右侧图一样

论文阅读:Training language models to follow instructions with human feedback

Ouyang L, Wu J, Jiang X, et al. Training language models to follow instructions with human feedback[J]. Advances in neural information processing systems, 2022, 35: 27730-27744. 引言 引言首先指出了当前大型语言模型(LMs)存在的一个核心问题:模型规模变大并不意味着它们能更好地遵循用户的意图 。具体而言,大型模型经常生成不真实、有毒或对用户毫无帮助的输出,这是因为语言模型的训练目标(预测网页上的下一个 token)与用户希望的目标(“有用且安全地遵循指令”)是错位的。作者的目标是让模型在“有用性”(Helpful)、“诚实性”(Honest)和“无害性”(Harmless)这三个方面与用户意图对齐。