GitHub - JRJRJPRO/tablecoder-rl: Post-training a small LLM for table numerical reasoning: execution-feedback GRPO + PRM-lite process reward + best-of-n test-time compute. Runs on a single 24GB GPU. · GitHub
Skip to content

About

Post-training a small LLM for table numerical reasoning: execution-feedback GRPO + PRM-lite process reward + best-of-n test-time compute. Runs on a single 24GB GPU.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

TableCoder-RL

用"代码执行沙盒的真实反馈"对小模型做后训练,专攻表格数值推理。 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)即可全流程复现。

动机

大模型在「表格 + 混合文本」上做数值计算是当前公认的薄弱环节:直接心算容易幻觉, 数值精度没有保障。本项目走"写代码代替心算"的路线,并回答三个问题:

  1. 异构数据理解:模型能否读懂多张关联表(含脏数据)并写出正确的 pandas 分析代码?
  2. 执行反馈 RL:摒弃人类偏好奖励,用代码在沙盒里真实执行的结果当奖励信号, GRPO 能带来多少提升?
  3. 过程奖励与测试时扩展:步骤级的 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 自动生成)。

模型 pass@1 (greedy) 执行率 verifier@8 oracle@8
Qwen2.5-0.5B-Instruct (base) – – – –
+ SFT – – – –
+ SFT + GRPO – – – –

test-time compute 曲线

与真实生产系统的差距(诚实清单)

  • 表格是合成的电商双表;真实商业数据是百万行、几十列、schema 千奇百怪的 CSV/Excel,需要 schema linking 与表格检索(列多到塞不进上下文)。
  • PRM-lite 是启发式;工业界会用蒙特卡洛 rollout 标注 + 训练步骤打分模型。
  • 0.5B/1.5B 底座是为了单卡可复现;结论的量级会变,但"执行反馈 > 纯 SFT" 与"验证器 + 测试时扩展有效"这两条曲线的形状是稳的。

开发方式

本项目由作者设计任务/奖励机制/实验方案,并深度使用 Claude Code 作为结对工程副驾 完成编码与调试——agent 写、人审查与验证(tests/test_smoke.py 是这套协作的 质量闸门)。License: MIT.

About

Post-training a small LLM for table numerical reasoning: execution-feedback GRPO + PRM-lite process reward + best-of-n test-time compute. Runs on a single 24GB GPU.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages