Prhub

#5713 [3/n][reward] feat: flowgrpo - support image-based rewards (rule-based & genrm)

verl-project/verl · 作者 chenyingshu · 合并时间 2026-03-26 15:54

分析状态 已生成
文件变更 10提交数 16 · 评论 12
代码增减 +590 / -19
reward trainer misc

执行摘要

添加图像奖励支持,用于 FlowGRPO 训练,扩展奖励系统以处理视觉输入。

PR body 指出这是 #4639 和 #5297 的后续工作,用于支持 FlowGRPO 训练 QwenImage。Issue 评论中 yyDing1 表示之前实现不支持图像/视频奖励模型,例如 compute_score 函数不接受 solution_image 参数,因此需要此变更来扩展功能。

推荐技术管理者和工程师精读此 PR,关注 VisualRewardManager 的设计和奖励循环的多模态扩展。值得注意的设计决策包括奖励管理器基类的扩展、异步处理实现、以及通过配置驱动的奖励函数选择,这些对于理解仓库架构演进有重要价值。

讨论亮点

review 中的核心讨论:gemini-code-assist[bot] 指出 compute_score_ocr 函数存在 ZeroDivisionError 风险(如果 ground_truth 为空字符串),建议添加边界检查;SamitHuang 提议将 ImageRewardManager 重命名为 VisualRewardManager 以覆盖图像和视频,作者采纳并修改;SamitHuang 和 zhtmike 讨论奖励函数放置位置,决定规则奖励放在 jpeg_compressibility.py,而 OCR 作为生成奖励模型示例;SamitHuang 建议通过 get_default_compute_score 函数改进 load_reward_manager 的代码结构,作者实现并更新 verl/utils/reward_score/__init__.py

实现拆解

实现方案拆解:1) 新增 VisualRewardManager 类(原为 ImageRewardManager),位于 verl/experimental/reward_loop/reward_manager/visual.py,作为奖励管理器基类的子类,专门处理视觉响应;2) 修改 RewardLoopManagerRewardLoopWorker_preprocess_reward_inputs 方法(在 verl/experimental/reward_loop/reward_loop.py),根据响应维度区分图像和文本输入;3) 添加奖励函数 compute_score_ocr(生成奖励模型,位于 examples/flowgrpo_trainer/reward_fn.py)和 jpeg_compressibility.compute_score(规则奖励,位于 verl/utils/reward_score/jpeg_compressibility.py);4) 新增工具函数如 pil_image_to_base64prepare_query_for_multi_modal(位于 verl/utils/experimental/reward_utils.py),以支持图像转换;5) 更新 CI 工作流(.github/workflows/reward_model_vllm.yml)添加测试,并提供单元测试脚本 tests/experimental/reward_loop/test_visual_reward_manager.py 验证功能。

文件 模块 状态 重要度
verl/experimental/reward_loop/reward_manager/visual.py reward_loop added 9.0
verl/experimental/reward_loop/reward_loop.py reward_loop modified 8.0
examples/flowgrpo_trainer/reward_fn.py examples added 7.0
tests/experimental/reward_loop/test_visual_reward_manager.py tests added 6.0
verl/utils/reward_score/__init__.py utils modified 7.0

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

关键符号

VisualRewardManager.run_single compute_score_ocr default_compute_score_image jpeg_compressibility.compute_score _preprocess_reward_inputs

评论区精华

OCR 奖励函数的 ZeroDivisionError 风险 正确性

gemini-code-assist[bot] 指出 compute_score_ocr 函数在 ground_truth 为空字符串时可能导致除以零错误,建议添加边界检查。

结论:作者未在 review 中明确修复,但提交历史显示代码更新,可能已处理此问题。 · 已解决

重命名奖励管理器以覆盖图像和视频 设计

SamitHuang 建议将 ImageRewardManager 改为 VisualRewardManager,以更全面地支持多模态输入,作者采纳建议。

结论:重命名为 VisualRewardManager,提升设计的通用性。 · 已解决

奖励函数代码结构改进 设计

SamitHuang 提议使用 reward_manager_cls.get_default_compute_score 来清理 load_reward_manager 逻辑,作者随后添加了 get_default_compute_score 函数。

结论:通过通用函数简化代码,提高可维护性。 · 已解决

风险与影响

技术风险具体包括:1) compute_score_ocr 函数在 ground_truth 为空字符串时可能引发 ZeroDivisionError,需要额外错误处理;2) 奖励管理器类型依赖配置字符串(如 'visual'),配置错误可能导致运行时问题;3) 异步处理和图像转换(如 pil_image_to_base64)可能引入性能开销或内存问题;4) 新增代码缺乏全面测试覆盖,仅提供单元测试示例,可能未覆盖所有边缘情况。

对用户:使研究人员能够使用图像奖励进行 FlowGRPO 训练,扩展了图像生成模型的应用场景;对系统:奖励循环现在支持多模态输入,增加了系统复杂性和维护负担;对团队:需要熟悉新的奖励管理器设计和多模态处理逻辑,可能影响后续开发和测试工作。

ZeroDivisionError 风险 配置字符串依赖 异步处理复杂 测试覆盖不足

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

执行摘要

本 PR 为 verl 仓库添加图像奖励支持,是 FlowGRPO 训练的关键扩展。通过新增 VisualRewardManager 类和修改奖励循环,实现了生成奖励模型(如 OCR)和规则奖励(如 JPEG 压缩性),使图像生成模型训练成为可能。变更影响奖励系统架构,提升了多模态能力,并提供测试验证。

功能与动机

动机源于之前奖励模型不支持图像/视频输入,限制了 FlowGRPO 训练的应用。PR body 指出这是 #4639 和 #5297 的后续工作,旨在支持 QwenImage 训练。Issue 评论中 yyDing1 确认了此需求,表示之前实现缺少对视觉输入的支持。

实现拆解

  • 新增 VisualRewardManager 类:位于 verl/experimental/reward_loop/reward_manager/visual.py,继承自 RewardManagerBase,专门处理视觉响应奖励计算,支持异步和同步评分。
  • 修改奖励循环:在 verl/experimental/reward_loop/reward_loop.py 中,_preprocess_reward_inputs 方法现在根据响应维度(3D 为图像,其他为文本)区分输入类型,实现多模态预处理。
  • 奖励函数实现
    • compute_score_ocr:位于 examples/flowgrpo_trainer/reward_fn.py,使用生成奖励模型进行 OCR 评分,基于 Levenshtein 距离计算匹配度。
    • jpeg_compressibility.compute_score:位于 verl/utils/reward_score/jpeg_compressibility.py,提供基于 JPEG 压缩性的规则奖励。
  • 工具函数:新增 pil_image_to_base64prepare_query_for_multi_modalverl/utils/experimental/reward_utils.py),支持图像到 base64 转换和多模态查询构建。
  • 测试与 CI:新增单元测试文件 tests/experimental/reward_loop/test_visual_reward_manager.py,并更新 CI 工作流(.github/workflows/reward_model_vllm.yml)以集成测试。

评论区精华

  • ZeroDivisionError 风险:gemini-code-assist[bot] 指出 compute_score_ocr 函数在 ground_truth 为空字符串时可能引发除以零错误,建议添加边界检查。作者在后续提交中可能已修复,但 review 中未详细说明。
  • 设计决策:SamitHuang 提议将 ImageRewardManager 重命名为 VisualRewardManager 以覆盖图像和视频,作者采纳并修改,体现了设计的前瞻性。
  • 代码结构优化:SamitHuang 建议通过 get_default_compute_score 函数改进 load_reward_manager 逻辑,作者实现此函数,简化了配置依赖。
  • 奖励函数放置:讨论规则奖励应放在 jpeg_compressibility.py,而 OCR 作为生成奖励模型示例,强调了模块化设计原则。

风险与影响

风险分析

  • 正确性风险compute_score_ocr 函数可能存在边界条件未处理,如空字符串导致的崩溃。
  • 配置风险:奖励管理器类型依赖字符串配置,错误配置可能引发运行时问题。
  • 性能风险:异步图像转换和网络请求可能增加延迟或内存消耗。
  • 测试风险:新增测试仅覆盖基本场景,缺乏全面边缘案例验证。

影响分析

  • 用户影响:研究人员现在可以使用图像奖励进行 FlowGRPO 训练,扩展了应用范围,尤其是图像生成领域。
  • 系统影响:奖励系统变得更加复杂,需要维护多模态处理逻辑,可能影响系统稳定性和性能。
  • 团队影响:开发人员需学习新模块,可能增加代码审查和维护成本。

关联脉络

本 PR 是系列工作的一部分,关联 PR #4639、#5297、#5616 和 #5716,共同推进 FlowGRPO 训练能力,特别是针对 QwenImage。从近期历史 PR 看,仓库正专注于扩展训练功能(如 #5745 的教师模型支持),本 PR 在多模态奖励方面填补了空白,显示了架构向更通用方向演进。

参与讨论