# 奖励模型

默认情况下，奖励模型是指具有分类头数值输出的模型，通常称为输出奖励模型（ORM）。这些模型会对其他模型的输出进行评分，从而生成一个标量值，表示模型响应的质量。

我们可以通过使用参数 `reward_models` 来加载具有分类头的奖励模型，或者加载经过[奖励建模](../../人类对齐.md#rm)训练的奖励模型，进而使用模型的logits作为奖励。

## 自定义奖励模型

目前，我们可以利用reward_model_plugin灵活地自定义奖励模型的处理逻辑。这使得实现诸如生成式奖励模型等技术成为可能，包括：
- 自定义模型的系统提示：定义特定的指令和上下文以指导评估过程。
- 处理模型交互历史：管理对话上下文，以提供有意义且具有上下文感知的评估。
- 定义自定义评估标准：设置独特的标准和度量，用于评估模型的响应，超越默认的准确性和相关性衡量标准。

通过reward_model_plugin，开发者可以针对其应用的特定需求定制奖励评估过程。这种灵活性允许更细致和有效的基于奖励的训练策略。

奖励模型通过plugin的`__call__`方法进行调用，该方法接受 `inputs` 作为参数，包含了模型输入输出的 messages 和数据集中的其他列

```python
    def __call__(self, inputs):
        print(inputs)
        """
[
    {
        'messages': [
                {'role': 'system', 'content': 'system prompt'},
                {'role': 'query', 'content': 'query'},
                {'role': 'user', 'content': 'completions1'},
            ],
        'solution': "abc",
    },
    {
        'messages': [
                {'role': 'system', 'content': 'system prompt'},
                {'role': 'query', 'content': 'query'},
                {'role': 'user', 'content': 'completions2'},
            ],
        'solution': "abc",
    }
]

```

对于生成式奖励模型，推荐使用 PTEngine 进行模型推理, 构造模型的输入的 messages 后使用infer接口进行推理
```python
class RMlugin(DefaultRMPlugin):

    def __init__(self, model, template):

        super().__init__(model, template)
        # initilize PTEngine to infer
        self.engine = PtEngine.from_model_template(self.model, self.template, max_batch_size=0)

        ...
        messages = [{'role': 'system', 'content': 'system prompt'}, {'role': 'query', 'content': 'query'}]
        result = self.engine.infer([messages], self.request_config, use_tqdm=False)
        print(result.message.content)
```


我们在 [rm_plugin.py](https://github.com/modelscope/ms-swift/blob/main/swift/plugin/rm_plugin.py) 中提供了一个简单的生成式奖励模型示例（GenRMPlugin）。

在 [plugin.py](https://github.com/modelscope/ms-swift/blob/main/examples/train/grpo/plugin/plugin.py) 中自定义奖励模型插件，并使用 `external_plugins` 参数进行注册。


以下是一个训练脚本示例，用于使用两个奖励模型，包括一个 ORM 和一个 Gen-RM（此处使用 qwen2.5-3B-Instruct）进行 GRPO 训练：

```bash
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
NPROC_PER_NODE=8 \
swift rlhf \
    --rlhf_type grpo \
    --model Qwen/Qwen2.5-7B \
    --dataset AI-MO/NuminaMath-TIR#5000 \
    --external_plugins examples/train/grpo/plugin/plugin.py \
    --reward_funcs format \
    --reward_model Qwen/Qwen2.5-3B-Instruct Shanghai_AI_Laboratory/internlm2-7b-reward \
    --reward_model_plugin genrm my_rmplugin \
    --reward_weights 0.1 1 1 \
    --vllm_gpu_memory_utilization 0.5 \
    --sleep_level 1 \
    --offload_model true \
    --offload_optimizer true \
    --log_completions true \
    --deepspeed zero2
```

注意：
1. 在 GRPOTrainer 中，reward_model 会依次append到 reward_funcs 中。因此，reward_weights 的顺序对应 [reward_funcs, reward_model]。
2. reward_model_plugin 默认为 default，即使用 ORM 处理逻辑。
3. 对于参数量较大的模型，PTEngine生成速度可能较慢，可以在外部部署模型，并在 reward_funcs 中进行调用


对于 BERT 这类无法通过 reward_model 加载的模型，我们可以内置在 reward_function 中进行加载，参考[issue](https://github.com/modelscope/ms-swift/issues/4580)
