Mind Lab Toolkit (MinT)
CustomizeRL

Code RL

Code RL 用基于执行的 reward 给生成的代码打分。Model 生成代码,沙箱里跑测试用例。Reward = 通过测试的比例(或二值:全过 → 1.0,任意失败 → 0.0)。这是"延迟 reward" —— policy 要等执行完才能拿到 reward。

参考 adapter 是 demos/rl/adapters/environment_tooluse.py,解决简单的函数编写题。

Configuration

用标准 GRPO 循环搭 Code RL,但 max_tokens 要更大以容纳代码:

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)

然后跑 code RL adapter:

from demos.rl.adapters.environment_tooluse import EnvironmentToolUseAdapter
from demos.rl.rl_core import RLConfig, run_grpo

cfg = RLConfig(
    model="Qwen/Qwen3-0.6B",
    rank=16,
    steps=10,
    batch=8,
    group=4,
    lr=2e-5,
    max_tokens=256,      # 写代码需要长很多
    temperature=0.8,
)

run_grpo(EnvironmentToolUseAdapter(), cfg)

Prompting Guide

代码题由 few-shot 示例和题目陈述组成:

class EnvironmentToolUseAdapter(RLAdapter):
    FEWSHOT = """Q: Write a function `double(x)` that returns x * 2.
A: ```python
def double(x):
    return x * 2
```

"""

    def make_prompt(self, sample: dict, tokenizer) -> list[int]:
        return tokenizer.encode(FEWSHOT + f"Q: {sample['q']}\nA:")

每个问题,model 生成含有代码的 response。Adapter 提取代码块(用 ```python ... ``` 的正则匹配),执行,再跑测试用例。

例题:

{
    "q": "Write `add(a, b)` that returns a + b.",
    "tests": [("add(1,2)", 3), ("add(-1,1)", 0)],
}

Model 生成:

def add(a, b):
    return a + b

Output Format

代码提取与执行:

def _extract_code(response: str) -> str | None:
    match = re.findall(r"```(?:\w+)?\n(.*?)```", response, re.DOTALL)
    if match:
        return match[-1].strip()
    if "def " in response:
        return response[response.find("def "):].strip()
    return None


def compute_reward(self, response: str, sample: dict) -> float:
    code = _extract_code(response)
    if not code:
        return 0.0
    try:
        ns: dict[str, Any] = {}
        exec(code, ns)  # 在隔离的命名空间里跑
        for expr, expected in sample["tests"]:
            if eval(expr, ns) != expected:  # 跑每个测试
                return 0.0
        return 1.0  # 全部通过
    except Exception:
        return 0.0  # 执行错或语法错

Reward 是二值:

  • 1.0:代码能提取、能执行、并通过所有测试用例。
  • 0.0:代码提不出来、跑不起来、或任意一个测试失败。

在一个 group 里,advantage 中心化:adv[i] = reward[i] - mean_reward

沙箱提醒: demo 在字典命名空间里直接用 exec() —— 不适合生产。真实部署要用合规沙箱(Docker、gVisor、Firecracker)隔离不受信任的代码。永远不要在不受信任的输入上跑这种代码。

All Parameters

参数类型默认值含义
stepsint10训练 step 数。
batchint8每 step 题目数。
groupint4每题样本数。
learning_ratefloat2e-5Adam 学习率。Code RL 取 1e-5 到 4e-5。
max_tokensint256最大生成长度。Code:128–512,看题目复杂度。
temperaturefloat0.8采样温度。典型值 0.7–1.0。
base_modelstr"Qwen/Qwen3-0.6B"base model。
rankint16LoRA rank。
train_mlpboolTrue训练 MLP。
train_attnboolTrue训练 attention。
train_unembedboolTrue训练输出层。

沙箱参数(环境特定):

  • sandbox_timeout_s:float —— 每次代码执行的超时。默认 5.0 秒。慢测试可调大。
  • max_tests_per_problem:int —— 最多跑多少测试用例。默认 10,封顶防止死循环。
  • partial_credit:bool —— 是否按通过测试比例给部分 reward(例如 2/4 → 0.5)。默认 False(二值 reward)。

环境变量:

export MINT_RL_MAX_TOKENS=256
export MINT_RL_STEPS=10
export MINT_RL_BATCH=8
export MINT_RL_GROUP=4
export MINT_RL_LR=2e-5

扩展到其它语言: demo 用的是 Python 的 exec()。换其它语言(JavaScript、Rust、Go)需要单独处理代码提取和编译。一般做法是只换 reward function,GRPO 循环本身不动。

本页目录