用"代码执行沙盒的真实反馈"对小模型做后训练,专攻表格数值推理。 Post-training a small LLM for table numerical reasoning via execution-feedback GRPO, with a PRM-lite process reward and best-of-n test-time compute.
麻雀虽小,五脏俱全:合成数据引擎 → SFT → 执行反馈 GRPO → 过程奖励 → 测试时扩展评测, 一条后训练流水线的每个环节都是真实可跑、可复现、可消融的。单张 24GB 卡(RTX A5000)即可全流程复现。
大模型在「表格 + 混合文本」上做数值计算是当前公认的薄弱环节:直接心算容易幻觉, 数值精度没有保障。本项目走"写代码代替心算"的路线,并回答三个问题:
- 异构数据理解:模型能否读懂多张关联表(含脏数据)并写出正确的 pandas 分析代码?
- 执行反馈 RL:摒弃人类偏好奖励,用代码在沙盒里真实执行的结果当奖励信号, GRPO 能带来多少提升?
- 过程奖励与测试时扩展:步骤级的 dense reward 和 best-of-n + 执行验证器, 分别还能再榨出多少准确率?
data_gen.py ──── 合成表格(orders/products) + 双语数值问题 + 程序化 gold + 参考解法
│ (10 模板 × 难度 L1~L4,L4 含脏数据清洗)
▼
make_sft_data.py → SFT 对(prompt → ```python 代码```)
▼
sft_train.py LoRA SFT:学会"看表→写代码→print 答案"的格式与基本功
▼
grpo_train.py GRPO:每题采样 G=8 条代码 ──► sandbox.py 真实执行
▲ │
│ 分级奖励 reward.py ◄────────────┘
│ 0 没代码 / 0.1 报错 / 0.3 跑通但答错 / 1.0 正确
│ (+ prm.py 过程奖励:逐语句前缀执行通过率,可选融合)
▼
evaluate.py pass@1 / 执行率 / 难度分桶
+ best-of-n(执行验证器+多数票) 的 test-time compute 曲线
pip install -r requirements.txt
# 不碰 GPU 的闭环冒烟(数据↔沙盒↔奖励↔PRM↔验证器 一致性,~1 分钟)
python tests/test_smoke.py
# 全流程(单卡,0.5B 底座,数小时)
bash scripts/run_all.sh奖励为什么分级而不是 0/1? 二值奖励对刚起步的策略太稀疏(组内全 0 时 GRPO
的组内归一化优势直接失效)。没代码 0 → 报错 0.1 → 答错 0.3 → 正确 1.0
给了爬坡的台阶:先学会格式,再学会跑通,最后学会算对。
过程奖励(PRM-lite):把代码按顶层语句切分、逐前缀丢进沙盒,
process_score = 干净执行的前缀比例。错在第 5 步的解比错在第 1 步的分高——
这是零训练成本的 dense reward。真 PRM(步骤级标注 + 训练打分模型)是它的升级版,
差距与升级路径见 src/prm.py 头注。
测试时扩展:n 个候选 → 丢弃执行失败的 → 答案多数票(self-consistency)提交。
执行验证器是表格任务的天然优势:验证一次几乎零成本,verifier@n 与
oracle@n(上界)的差距量化了验证器的损耗。
沙盒:AST 白名单(import/内建双重检查)+ python -I 子进程隔离 + 超时 +
Linux 下 RLIMIT 内存/CPU 上限。研究级隔离,生产化可替换为 docker/nsjail,
接口不变(run_code(code, tables) -> status/stdout/stderr)。
为什么合成数据? ①gold 程序化生成,绝对无标注噪声;②难度/脏数据可控可消融;
③参考解法经沙盒回放验证(tests/test_smoke.py),SFT 教师零幻觉。
迁移到真实数据(WikiTQ / TabMWP / 私有 CSV)只需换 data_gen.py 的产出格式。
训练进行中,本表随训练完成更新(
results/*.json由evaluate.py自动生成)。
- 表格是合成的电商双表;真实商业数据是百万行、几十列、schema 千奇百怪的 CSV/Excel,需要 schema linking 与表格检索(列多到塞不进上下文)。
- PRM-lite 是启发式;工业界会用蒙特卡洛 rollout 标注 + 训练步骤打分模型。
- 0.5B/1.5B 底座是为了单卡可复现;结论的量级会变,但"执行反馈 > 纯 SFT" 与"验证器 + 测试时扩展有效"这两条曲线的形状是稳的。
本项目由作者设计任务/奖励机制/实验方案,并深度使用 Claude Code 作为结对工程副驾
完成编码与调试——agent 写、人审查与验证(tests/test_smoke.py 是这套协作的
质量闸门)。License: MIT.

