MathForge is an adversarial synthesis pipeline for olympiad-grade math problems —
it forges high-difficulty, short-answer, machine-verifiable problems that are hard enough to
stump frontier LLMs (target: first-attempt pass_rate ≤ 80%).
Starting from a pool of hard seed problems, it generates new originals, filters out unreliable statements and invalid answer shapes, then uses a strong model (gpt-5.5) to solve each surviving problem from the statement alone and write the ground-truth answer plus a standard solution. Finally it gates each problem by having a target model actually attempt it — keeping only the ones it fails.
The stages are fully decoupled: generation never verifies (it just mass-produces at high concurrency); a separate filter rejects ill-posed or malformed generated statements; gpt-5.5 establishes ground-truth answers; difficulty only judges "hard or not".
seeds (data/seeds.jsonl) ← 任意格式新种子可经 `python -m mathforge.ingest` 归一入库
│
▼
[1] generate 种子调度器 + 出题(纯生成,满并发,不验证)
▼ generated.jsonl
[2] reliability filter deepseek-v4-flash 判断题干可靠性、边界漏洞、答案形态和 LaTeX 格式;不通过则不进 gpt-5.5/豆包
▼ generated.filtered.jsonl (+ generated.filtered.dropped.jsonl)
[3] batch verify gpt-5.5 只看题干独立解题(默认 10 题/次):返回 reliable + answer + solution
│ reliable=true → reference_answer/answer 覆盖为 gpt-5.5 答案,groundtruth_solution 写入解析
│ reliable=false → dropped,不进难度门
▼ verified.jsonl (+ verified.jsonl.dropped.jsonl)
[4] difficulty 难度门:目标模型(豆包)干净作答 K 次,对比真答案;做错=合格
▼ final.jsonl + final.qualified.jsonl
合格 = 筛选通过 ∧ gpt-5.5 给出标准答案/解析 ∧ 目标模型做错
为什么改用 gpt-5.5 解题定答案:旧的"模型写脚本本机实算"对纯证明/非数值题不适用; 裁判式 verify 又容易被 proposed answer 干扰。新流程只把题干发给强模型,让它独立给出
answer和solution,作为下游判分的 ground truth。
MathForge/
├── README.md
├── requirements.txt
├── run_pipeline.py # 一键全流程编排
├── data/
│ ├── seeds.jsonl # 默认种子池(193 = 93 成题 + 100 出题指令)
│ └── seeds_top93.jsonl # 93 颗成题种子(Omni-MATH 难度≥9,含 question/answer)
├── docs/
│ └── prompt.md # 提示词规范(IMO 风格 / 对抗强化版)
└── mathforge/ # 主包
├── config.py # 端点 / 各环节默认模型 / API key 解析
├── llm.py # 异步客户端、重试、JSON 解析
├── ingest.py # 种子接入:任意格式 → 标准 schema 并追加入库(去重/备份/dry-run)
├── prompts.py # 全流程提示词
├── scheduler.py # 种子调度器(加权采样+反馈调权)
├── generate.py # 阶段一 · 纯出题
├── reliability_filter.py # 阶段二 · 题干可靠性 + 答案形态预筛
├── batch_verify.py # 阶段三 · gpt-5.5 只看题干,写答案 + 解析
├── difficulty.py # 阶段四 · 豆包难度门(做错=合格)
├── verify.py # (旧)独立计算验证,保留备用,不在新流程使用
└── sandbox.py # (旧)计算脚本本地执行,配合 verify.py
新种子可能是任意字段格式(json/jsonl/csv/tsv)。用 ingest 自动按别名映射到标准 schema、
按"题面+答案"去重、追加进 data/seeds.jsonl(自动备份 .bak),之后照常出题:
# 先预览(不写库):看清字段映射 / 缺字段 / 重复 / 新增
python -m mathforge.ingest --input new_seeds.csv --dry-run
# 字段名不标准时手动指定映射,然后入库
python -m mathforge.ingest --input new_seeds.csv --map question=problem answer=label --source batchA常见别名自动识别(如
problem/stem→question、label/gt→answer、topic→category); 无答案的记录会被当作seed_type=directive(出题方向指令)入库。
pip install -r requirements.txt需要一个 aihubmix 的 API key(OpenAI 兼容端点)。
API key 不写进代码,通过命令行 --api-key 或环境变量 AIHUBMIX_API_KEY 提供。
# key 作为启动参数
python run_pipeline.py --api-key sk-xxxxxx --num 30
# 或先设环境变量
export AIHUBMIX_API_KEY=sk-xxxxxx
python run_pipeline.py --num 30产物默认在 ./output/:generated.jsonl → generated.filtered.jsonl → verified.jsonl → final.jsonl,
其中合格题会单独追加到 final.qualified.jsonl。
# ① 出题:满并发大批量产题,不做任何验证
python -m mathforge.generate --api-key sk-xxx --num 200 --concurrency 30 --output output/generated.jsonl
# ② 题干可靠性+答案形态预筛:不通过则不进 gpt-5.5/豆包
python -m mathforge.reliability_filter --api-key sk-xxx --input output/generated.jsonl --reliable-output output/generated.filtered.jsonl --unreliable-output output/generated.filtered.dropped.jsonl
# ③ gpt-5.5 解题:只给题干,一次处理一批,返回 reliable + answer + solution
# 输出 verified.jsonl(可靠且有答案+解析) 与 verified.jsonl.dropped.jsonl(不可靠/缺字段/API异常)
python -m mathforge.batch_verify --api-key sk-xxx --input output/generated.filtered.jsonl --output output/verified.jsonl
# ④ 豆包难度门:目标模型作答 K 次,对比 gpt-5.5 真答案,做错=合格(--no-rubric)
python -m mathforge.difficulty --api-key sk-xxx --input output/verified.jsonl --output output/final.jsonl --no-rubric| 环节 | 默认模型 |
|---|---|
| 出题 / 改写 / 对抗 | deepseek-v4-flash |
| 题干可靠性 + 答案形态预筛 | deepseek-v4-flash |
| gpt-5.5 解题定 ground truth(只给题干,返回答案+解析) | gpt-5.5(batch=10) |
| 难度门 · 目标模型(被挑战者) | doubao-seed-2-0-pro |
| 难度门 · 判分(目标答案≟真答案) | deepseek-v4-pro |
每条记录是统一 schema,依次累积各阶段产物:
- 出题:
question/answer/answer_format/key_points/from_seeds/gen_mode - 题干可靠性预筛:
reliability_filter.{reliable, model_reliable, quality_score, difficulty_score, combined_score, reason, difficulty_reason}; 其中difficulty_score保留为兼容字段,当前预筛不按难度或题型偏好拦截 - batch verify:
batch_verify.{usable, reliable, reliability_reason, model_answer, original_answer, answer_corrected, solution}, 并把answer/reference_answer覆盖为 gpt-5.5 答案,groundtruth_solution写入标准解析 - 难度门:
difficulty_gate.{verdict, rubric_score, rubric, solved, k, correct_count, rollouts[]}、difficulty.pass_rate/difficulty.doubao_solved - 合格题单独文件:
final.qualified.jsonl,只包含difficulty_gate.verdict == "合格"的题
其中 groundtruth_solution 是 gpt-5.5 在 batch verify 阶段生成的标准题目解析;
rollouts[] 保留目标模型每次作答的 final_answer 与完整解答全文 solution。
- API key 安全:切勿把 key 提交到仓库;
.gitignore已忽略.env与output/。 - 沙箱:验证阶段会本地执行 LLM 生成的计算脚本(已加超时与临时目录隔离),生产环境建议放进容器 / nsjail。
- 速度:
deepseek/doubao多为重推理模型,单题可能数分钟,请用--concurrency提升吞吐。 - 难度:默认不对抗(
--adv-rounds 0)直接出题,速度快;如需更难,可加--adv-rounds 2开启对抗。 - 验证适用范围:独立计算验证对有确切数值/可程序化答案的题是客观判定;纯证明/开放题不适用。