Mind Lab Toolkit (MinT)
CustomizeRL

RL 概览

强化学习(RL)通过从 policy 采样、给输出打分、把 reward 信号反向传播回去,来更新 policy。MinT 用 GRPO(Group Relative Policy Optimization)—— 它在同一个 prompt 的一组样本内对 advantage 做归一化,让训练更稳。

RL 循环:

  1. 采样:当前 policy 对每个 prompt 生成多个 response。
  2. 评分:用 reward function 给每个 response 打分(verifier、judge 或环境)。
  3. 算 advantage:在 group 内把 reward 中心化。
  4. 训练:用 loss_fn="importance_sampling" 对采样到的 trajectory 训练。

Reward 来源可插拔,所以 RL 适用于数学(精确匹配 verifier)、聊天(偏好 judge)、代码(执行测试)或自定义信号。

Configuration

最小化 RL 训练循环:

import mint
from mint import types

service_client = mint.ServiceClient()
training_client = service_client.create_lora_training_client(
    base_model="Qwen/Qwen3-0.6B",
    rank=16,
    train_mlp=True,
    train_attn=True,
    train_unembed=True,
)

tokenizer = training_client.get_tokenizer()
adam_params = types.AdamParams(learning_rate=2e-5)

for step in range(num_steps):
    # 1. 从当前 policy 采样
    sampling_client = training_client.save_weights_and_get_sampling_client(
        name=f"rl-step-{step}"
    )

    # 2. 收集样本,算 reward(见 RL demo)
    training_datums: list[types.Datum] = [...]
    
    # 3. 用 importance sampling 训练
    training_client.forward_backward(
        training_datums, 
        loss_fn="importance_sampling"
    ).result()
    training_client.optim_step(adam_params).result()

生产级的 RL 循环参考 demos/rl/rl_core.py,它实现了 run_grpo(adapter) 共享基础设施,下面提到的任务特定 adapter 都基于它。

Prompting Guide

RL prompt 通常比 SFT 短 —— model 要生成完整的 response,而不是按固定模板补全。例如:

  • Math: "Q: What is 3 + 5?\nA:"
  • Chat: 用户消息按 chat template 格式化,并带 add_generation_prompt=True
  • Code: 题目陈述 + few-shot 示例 + "A:"(model 续写代码)。

prompt encode 完传给 sampling_client.sample(...)

prompt_tokens = tokenizer.encode("Q: What is 3 + 5?\nA:")

result = sampling_client.sample(
    prompt=types.ModelInput.from_ints(tokens=prompt_tokens),
    num_samples=8,  # 每个 prompt 采 8 个 response
    sampling_params=types.SamplingParams(
        max_tokens=16,
        temperature=0.8,  # 控制探索;温度越高越多样
        stop_token_ids=[tokenizer.eos_token_id],
    ),
).result()

for seq in result.sequences:
    response_text = tokenizer.decode(seq.tokens)
    logprobs = seq.logprobs or [0.0] * len(seq.tokens)

返回的每个 sequence 带:

  • tokens:生成的 token ID。
  • logprobs:当前 policy 下 per-token 的 logprob。

Output Format

RL 用的是 advantage,不是原始 reward。标准模式:

  1. 收集 reward:拿到 group 内所有样本的 reward。
  2. 算 group 均值mean_r = sum(rewards) / num_samples
  3. 中心化 advantageadvantage[i] = reward[i] - mean_r
  4. 构造 Datum:prompt 部分 loss_weights 设 0,response 部分填 advantage。

来自 quickstart.py 的例子:

g_rewards, g_responses, g_logprobs = [], [], []
for seq in res.sequences:
    txt = tokenizer.decode(seq.tokens)
    reward = 1.0 if extract_answer(txt) == gold_answer else 0.0
    g_rewards.append(reward)
    g_responses.append(list(seq.tokens))
    g_logprobs.append(list(seq.logprobs or [0.0] * len(seq.tokens)))

mean_r = sum(g_rewards) / len(g_rewards)
advs = [r - mean_r for r in g_rewards]

for resp_tok, lp, adv in zip(g_responses, g_logprobs, advs):
    if not resp_tok:
        continue
    full = prompt_tokens + resp_tok
    prefix = len(prompt_tokens) - 1
    datums.append(
        types.Datum(
            model_input=types.ModelInput.from_ints(tokens=full[:-1]),
            loss_fn_inputs={
                "target_tokens": full[1:],
                "weights": [0.0] * prefix + [1.0] * len(resp_tok),
                "logprobs": [0.0] * prefix + lp,
                "advantages": [0.0] * prefix + [adv] * len(resp_tok),
            },
        )
    )

Loss 按 advantage 缩放:reward 高于 mean_r 的样本拿到正梯度,低于 mean_r 的拿到负梯度。这会推 policy 提高高 reward 样本的概率,压低低 reward 样本的概率。

All Parameters

参数类型默认值含义
loss_fnstr"importance_sampling"GRPO 是默认推荐的 RL 算法。备选(服务端接受,参考脚本未演示):"ppo""cispo""dro"
group_sizeint4每个 prompt 的采样数。group 越大方差越小,但显存占用也越大。典型值 4–16。
batch_size(或 groups_per_batchint8每个 training step 的 prompt 数。
max_tokensint16每个样本最长生成长度。按任务调:math ≈ 16,chat ≈ 128,code ≈ 256。
learning_ratefloat2e-5Adam 学习率。RL 一般比 SFT 低(1e-5 到 4e-5)。
temperaturefloat0.8采样温度。越高探索越多。RL 典型值 0.7–1.0。
kl_penalty_coeffloat0.0KL 散度惩罚(参考 model vs policy)。设 > 0 会给 loss 加 coef * KL,防止 policy collapse。
betastuple[float, float](0.9, 0.999)Adam 一阶 / 二阶矩的指数衰减率。
epsfloat1e-8Adam 数值稳定项。
weight_decayfloat0.0L2 正则化。
base_modelstr"Qwen/Qwen3-0.6B"base model ID。
rankint16LoRA rank。
train_mlpboolTrue训练 MLP 层。
train_attnboolTrue训练 attention 层。
train_unembedboolTrue训练输出层。

用法:

adam_params = types.AdamParams(learning_rate=2e-5)
result = training_client.forward_backward(
    datums,
    loss_fn="importance_sampling"
).result()
training_client.optim_step(adam_params).result()

任务特定 RL: 具体的 reward 实现见 Math RLChat RLCode RL

What's next?

  • Math RL —— 用确定性 verifier 做精确匹配评分。
  • Chat RL —— 用 judge model 给出基于偏好的 reward。
  • Code RL —— 用沙箱执行得到的 reward。
  • rl_core.py —— GRPO 共享循环和 RLAdapter 协议。

本页目录