多模态GRPO完整实验流程
本文介绍如何使用SWIFT GRPO进行多模态模型和任务的训练。目标是对多个多模态任务进行训练,提升任务精度,任务定义和训练参数等参考了 R1-V 和 open-r1-multimodal
ClevrCount 任务
任务与数据集定义
本任务从clevr_cogen_a_train数据集出发,模型的目标是输出图像中包含的物体数量,因此,我们定义数据集如下:
class ClevrPreprocessor(ResponsePreprocessor):
def preprocess(self, row: Dict[str, Any]) -> Dict[str, Any]:
query = row.get('query', '')
query = f"""{query} Output the thinking process in <think> </think> and
final answer (number) in <answer> </answer> tags."""
row.update({'query': query})
return super().preprocess(row)
register_dataset(
DatasetMeta(
ms_dataset_id='okwinds/clevr_cogen_a_train',
subsets=[
SubsetDataset(
name='default',
subset='default',
split=['train'],
),
],
preprocess_func=ClevrPreprocessor(),
tags=['qa', 'math']))
这里重新定义dataset preprocessor的目的是修改query。数据集示例样本如下,包含messages,images和solution字段,solution会送入后续的奖励函数中,而messages和images则会作为模型输入。
-
注意:
{'role': 'assistant', 'content': '<answer> 3 </answer>'}
将会在GRPOTrainer中被移除,可以忽略。'solution'字段将会透传入ORM中。在自定义数据集时,'images'字段组织成["image_path1", "image_path2"]
即可。
{ 'images': [{'bytes': b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\xe0\x00\x00\x01@\x08\x06\x00\x00\x00d\xc8\xafB`\x82 ...', 'path': 'CLEVR_trainA_000000.png'}], 'messages': [{'role': 'user', 'content': 'How many items are there in the image? Output the thinking process in <think> </think> and\n final answer (number) in <answer> </answer> tags.'}], 'solution': '<answer> 3 </answer>' }
奖励函数定义:
本任务使用的奖励函数有两个,一个是 Deepseek-R1 中提到的格式奖励函数,另一是 ClevrCount 的准确性奖励函数。前者已经在swift中内置,通过 --reward_funcs format
可以直接使用,而后者需要我们自己定义,在这里我们使用 external_plugin 的方式定义准确性奖励函数,将代码放在swift/examples/train/grpo/plugin/plugin.py
中。
在这里,奖励函数的输入包括completions和solution两个字段,分别表示模型生成的文本和真值。每个都是list,支持多个completion同时计算。注意,在这里,solution字段是数据集中定义的字段透传而来,如果有任务上的变动,可以分别对数据集和奖励函数做对应的改变即可。