Code RL¶
Code RL 通过运行生成的代码来给分。模型生成代码,沙箱里跑测试用例。Reward 是通过测试的比例,或者二值信号:全过得 1.0,任意失败得 0.0。因为 reward 取决于执行结果,策略要等代码跑完才能拿到 reward —— 这是一种延迟 reward。
参考 adapter 是 demos/rl/adapters/environment_tooluse.py,解决简单的函数编写题。
Configuration¶
用标准 GRPO 循环搭 Code RL,但 max_tokens 要更大,给代码留出空间:
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:")
每个问题,模型生成一个含代码的回复。Adapter 用 ```python ... ``` 的正则匹配提取代码块,执行,再跑测试用例。
例题:
模型生成:
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。
Warning
沙箱提醒: demo 在字典命名空间里直接调用 exec() —— 不能用于生产环境。真实部署要用合规沙箱(Docker、gVisor、Firecracker)隔离不受信任的代码。不要在不受信任的输入上运行这类代码。
All Parameters¶
| 参数 | 类型 | 默认值 | 含义 |
|---|---|---|---|
steps |
int | 10 |
训练 step 数。 |
batch |
int | 8 |
每 step 题目数。 |
group |
int | 4 |
每题样本数。 |
learning_rate |
float | 2e-5 |
Adam 学习率。Code RL 取 1e-5 到 4e-5。 |
max_tokens |
int | 256 |
最大生成长度。Code:128–512,看题目复杂度。 |
temperature |
float | 0.8 |
采样温度。典型值 0.7–1.0。 |
base_model |
str | "Qwen/Qwen3-0.6B" |
base model。 |
rank |
int | 16 |
LoRA rank。 |
train_mlp |
bool | True |
训练 MLP。 |
train_attn |
bool | True |
训练 attention。 |
train_unembed |
bool | True |
训练输出层。 |
沙箱参数(环境特定):
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
Note
扩展到其它语言: demo 用的是 Python 的 exec()。换其它语言(JavaScript、Rust、Go)需要单独处理代码提取和编译。常见做法是只换 reward function,GRPO 循环本身不动。