使用 GRPO 训练 Qwen3-VL 视觉语言推理任务#

本文档介绍了如何在 RLinf 框架下,使用强化学习(RL)来训练视觉语言模型(VLM)以进行几何推理。

环境要求与安装#

依赖版本

Qwen3-VL 系列模型需要较新版本的依赖库:

  • torch >= 2.8.0

  • sglang == 0.5.4

  • transformers == 4.57.1

较低版本的 sglang 或 transformers 不支持或者不能正确支持 Qwen3-VL 系列模型。

一键安装

RLinf 提供了 requirements/install.sh 脚本一键完成环境安装:

export MEGATRON_PATH=/path/to/Megatron-LM
bash requirements/install.sh agentic \
    --torch 2.8.0 \
    --sglang 0.5.4 \
    --transformers 4.57.1 \
    --no-apex

脚本会自动完成安装步骤

备注

MEGATRON_PATH 需要指向一个已有的 Megatron-LM 仓库克隆(推荐 core_r0.13.0 分支)。 如果该目录不存在,安装脚本会提前退出,不执行后续的 flash-attn 和 apex 安装步骤。

小技巧

由于本例子使用 FSDP2 作为训练后端,apex 不是必需的,所以通过 --no-apex 开关避免了安装apex。 如果系统 CUDA 工具链版本(nvcc --version)与 PyTorch 编译使用的 CUDA 版本不一致, apex 可能无法从源码编译。

安装后验证

安装完成后,可以通过以下命令验证关键依赖是否安装成功:

source .venv/bin/activate
python -c "
import torch; print('torch:', torch.__version__)
import transformers; print('transformers:', transformers.__version__)
import sglang; print('sglang:', sglang.__version__)
print('All good')
"

数据集#

我们使用 geo3K 数据集(从 https://huggingface.co/datasets/CAIR-HKISI/geo3k 下载),该数据集包含几何问题及其对应的图像和答案。

一个训练样例如下:

{
   "problem": "<image>\nProblem description",
   "images": An numpy.ndarray of image bytes,
   "answer": "\\boxed{x}"
}

备注

geo3k 数据集有多种保存形式,如果您从其他地址下载,图片数据可能通过 base64 或者 PIL.Image 格式保存,需要仔细进行适配

我们支持多种数据集格式配置:

  • Prompt key 和 answer key 配置

    默认配置要求数据集使用 problemanswer 键分别用于获取提示词信息和答案信息。 在配置 yaml 文件中修改 prompt_keyanswer_key 的值,使其指向数据集中对应的字段即可。

    prompt_key: "problem"
    answer_key: "answer"
    
  • 图像数据配置

    对于视觉语言任务,需要配置 image_keys 参数指定图像字段名称:

    image_keys: ["images"]
    
  • 图像占位符解析

    数据集支持在 prompt 中使用 <image> 占位符来标记图像位置。框架会自动解析占位符并将文本与图像交叉排列。 如果 prompt 中不包含占位符,则图像会被放置在文本之前。

  • system_prompt 配置

    如果需要在数据集原有的 prompt 之前添加统一的提示词,可以使用 system_prompt 配置:

    system_prompt: 'Solve the following math problem step by step. The last line of your response should be of the form Answer: \\boxed{$Answer}.'
    

算法#

我们采用标准的 GRPO(Group Relative Policy Optimization),并且通过配置项打开了**TIS**(截断重要性采样)以稳定训练:

importance_sampling_fix: True
importance_sampling_clip: 2

实验证明,打开 TIS 可以避免熵的无序增加和序列长度的过快增长,从而获得更稳定的训练。

奖励函数:

  • 正确:+1(可通过 reward_max_val 配置)

  • 错误:0(可通过 reward_min_val 配置)

运行脚本#

1. 配置文件

推荐配置示例:

  • examples/reasoning/config/vqa/qwen3-vl-2b-grpo-fsdp-geo3k.yaml

2. 关键参数配置

在启动前,检查配置文件。主要字段包括:

  • 路径:rollout.model.model_path (基础模型本地路径)、data.train_data_paths (训练数据路径)等。

  • 模型类型:rollout.model.model_type 需设置为 qwen3_vl

3. 启动命令

运行以下命令以启动 Ray 集群并开始训练:

cd /path_to_RLinf/ray_utils;
rm /path_to_RLinf/ray_utils/ray_head_ip.txt;
export TOKENIZERS_PARALLELISM=false
bash start_ray.sh;
if [ "$RANK" -eq 0 ]; then
    bash check_ray.sh 4
    bash examples/reasoning/run_main_grpo_vqa.sh qwen3-vl-2b-grpo-fsdp-geo3k
else
  sleep 10d
  rm ray_utils/ray_head_ip.txt;
fi

sleep 10d

技术细节#

序列打包(Packing)

为了提高训练效率,框架支持动态序列打包功能。当启用 enable_dynamic_batch_size: True 时, 多个短序列会被打包成一个长序列进行训练。可以通过以下参数控制打包行为:

  • max_tokens_per_mbs:每个 micro-batch 的最大 token 数

  • variable_seq_lengths:是否允许变长序列,设为 False 时,还会将打包后的长序列 pad 到固定长度,这有可能在某些场景下避免重复compile等问题. 本例中我们设为 True

FSDP2 训练

Qwen3-VL 训练使用 FSDP2 作为训练后端。关键配置包括:

actor:
  fsdp_config:
    strategy: "fsdp2"
    gradient_checkpointing: True
    gradient_checkpointing_use_reentrant: False

Rollout 与训练的 KL 监控

框架新增 actor/rollout_train_kl 指标,用于监控 rollout 阶段和训练阶段 logprobs 之间的差异, 帮助诊断训练稳定性问题。打开 recompute_logprobs 和 return_logprobs 后会自动显示该曲线。

结果#

我们使用 Qwen3-VL-2B-Instruct 进行了实验,训练曲线如下:

reward with TIS

entropy with TIS

可以看到进行了750步训练后,reward 仍有上涨趋势;且 entropy 趋于收敛。

如果关闭 TIS,则有很大的可能性导致一定步数后 reward 曲线崩溃,且 entropy 较不稳定:

reward without TIS

entropy without TIS