首页 / 模型排行 / 正文
模型排行

数学竞赛题模型评测全指南:避开数据集与评分误区,看清模型真实推理能力

chuanbook chuanbook
发布于 2026 年 10 月 22 日
阅读 约27分钟
浏览 3
评论 0

我最早开始认真琢磨“数学竞赛题模型评测”这件事,其实是从一次很具体的失败体验来的。当时我拿一道不算太难的平面几何题去试某个声称“数学能力大幅提升”的大模型,题目本身只涉及相似三角形和圆的基本性质,推理链大概五六步。模型洋洋洒洒写了两百多个字,每一步看起来都像模像样,结论却和标准答案差了一个符号。我把它写的证明贴给一个教竞赛的朋友看,对方扫了两眼就笑了:“这段推理在第二步就偷偷用了一个没有证明的假设。”

那次经历让我意识到一个挺尴尬的问题——我们平时说“模型数学能力很强”,和“模型能处理数学竞赛题”之间,隔着的远不止一个难度等级。竞赛题对推理链条的容错率极低,中间任何一个隐含假设、一次范围讨论的遗漏、一处特殊情况的忽略,都会直接导致答案失效。通用数学评测里常见的那些“看最后数字对不对”的判分方式,放到竞赛场景里几乎立刻失灵。这也是我为什么觉得,得先把竞赛题的特点和模型能力的真实挑战讲清楚,后面的评测设计才有立足点。

1.1 数学竞赛题的特点与模型能力挑战

我自己做竞赛题训练的体会是,竞赛题最磨人的地方在于它几乎不给你“照着套路走”的空间。一道好的竞赛题往往把多个知识点拧在一起,你要先自己判断该往哪个方向破题,用哪种构造、哪条辅助线、哪个不变量。这种“先选路再走路”的能力,和模型擅长的那种“给定模式匹配已知解法”的路径非常不一样。我观察过不少模型在组合题上的表现,它们经常能写出前两步看起来很漂亮的分类讨论,到一个需要自己构造函数或找奇偶性不变量的地方就卡住,然后开始重复之前的思路打转。

另一个让我印象深刻的点是表述的稠密程度。竞赛题的题干通常很短,但每个条件都几乎不可或缺,删掉任何一个都可能导致题目无解或者变成另一个问题。模型在做这种“信息密度极高”的题时,很容易把某个条件理解偏或者悄悄弱化。我见过模型把“正实数”当成“实数”来用,结果本该舍掉的负根被它留下,这类错误在普通应用题里可能无伤大雅,在竞赛题里就是致命的。所以在我看来,竞赛题对模型提出的挑战不只是计算复杂度,更是对约束条件的忠实度和对推理链条的自我监控能力。

还有一层挑战我觉得挺少被讨论的,就是竞赛题的多解性和解法优雅度的问题。同一道几何题可能有纯几何做法、三角做法、解析做法,每种路径的推理长度和易错点完全不同。模型如果只是“凑”出一个能到达终点的解法,这本身不算错,但评测时会发现不同解法之间步骤的可比性很差。我在整理评测记录时常常遇到这种情况:两个模型答案都对,但一个用了四步干净利落的构造,另一个绕了十几步其中还夹着两处数值验算。这两种回答在“正确性”指标上无法区分,可它们反映出的模型能力差异其实很大。竞赛题本身的这种解法多样性,让我在设计评测时必须同时考虑结果和过程两个层面。

1.2 模型评测的目标、边界与应用场景

说到评测目标,我自己的定位一直比较克制。我做数学竞赛题模型评测,不是为了给模型排一个“谁更聪明”的座次表,而是想回答一些更具体的问题:模型在什么类型的推理上会系统性出错?它的错误是知识缺失、步骤跳跃,还是约束条件处理不当?不同提示方式下它的稳定性差多少?这些问题对模型训练和数据构建是有直接反馈价值的。我经常跟朋友打比方说,评测更像是一次体检,一份详细的错误类型分布比一个总分有用得多。

边界这块我也踩过不少坑。最开始我想着“竞赛题评测嘛,把历年真题收集齐就行了”,做起来才发现事情没那么简单。不同竞赛的命题风格差异很大,联赛题、冬令营题、IMO 题之间的难度跨度不是线性的,有些题难在技巧刁钻,有些题难在计算量巨大,把它们混在一起算一个平均分意义不大。我后来倾向于把评测边界划清楚:明确评测覆盖的知识范围(比如代数、几何、数论、组合四大块)、明确难度分层标准、明确只评“可验证的最终结论”还是也评推理过程。边界不清楚,评测结果就很容易被误读。

应用场景方面,我觉得最有价值的其实是两个方向。一个是给模型研发团队提供细粒度的能力画像,比如发现模型在数论的同余分析上表现相对稳定,但在几何的辅助线构造上明显偏弱,这种信息可以直接指导后续的数据配比和训练策略。另一个是给教育场景里的使用者提供参考,比如一个老师想用模型辅助竞赛辅导,他需要知道模型在哪些题型上的输出可以直接参考、哪些需要人工核验。这两个场景对评测的侧重点其实不太一样,前者更关心错误分布,后者更关心高风险错误的发生率。我在设计评测方案时会尽量把这两类需求分开考虑,而不是试图用一套指标同时满足。

1.3 从通用数学评测到竞赛级评测的递进逻辑

我回头看自己用过的那些通用数学评测集,像小学数学应用题、初中代数计算这类,它们的设计逻辑和竞赛题评测确实有本质区别。通用评测更多是在检验模型对基本概念和标准解法的掌握程度,题目往往有一个明显的“标准路径”,答案形式也比较单一。这类评测当然有意义,它能快速筛出模型在基础运算和简单推理上的问题。可一旦模型在这些基础评测上普遍拿到高分,继续用它们来区分模型能力就变得很困难了,分数会挤在高位区间,失去分辨力。

竞赛级评测的出现,我理解是被这种“天花板效应”逼出来的。当基础题不再能拉开差距,就需要找到那些能暴露模型推理短板的题目类型。竞赛题恰好具备几个特点:推理链更长、隐含假设更多、解法的多样性更高、错误更容易在中间步骤埋下。这些特点让竞赛题成为一种天然的“压力测试”场景。我自己在做对比时就发现,同一个模型在通用评测上得分接近满分,换到竞赛题上正确率可能掉到三成以下,而且错误类型非常集中,大多出在需要多步构造和分类讨论的地方。

这种递进关系我觉得不只是难度上的加码,更是评测维度上的扩展。通用评测主要看“结果对不对”,竞赛级评测必须引入“过程可不可信”这个维度。我经常提醒自己,从通用到竞赛不是简单地把题目变难,而是要把评测的关注点从答案匹配迁移到推理质量上。这个迁移过程里,很多在通用评测中好用的指标和方法都需要重新设计,不能直接套用。这也是我后面要花大量篇幅去讨论数据集构建、过程指标和评分协议的原因——竞赛级评测真正难的地方,从来都不是找几道难题那么简单。

数据集这件事,我一开始想得特别简单:把能找到的竞赛题都收进来,标上答案,不就是一个评测集了吗?真动手做了三个月之后,我才明白这里面最难的部分根本不是收集题目,而是决定一道题以什么样的形式进入数据集。同一道题,题干怎么表述、答案验证做到什么程度、推理步骤标注到哪一层、是否允许一题多解,这些选择会直接决定评测结果的含义。我后来跟一个做机器学习的朋友聊这件事,他说了一句让我印象很深的话:“数据集不是题目的集合,而是评测意图的物化。”这话有点绕,但确实说出了我踩坑之后的核心体会。

2.1 竞赛题来源、难度分层与知识点覆盖

来源这块我吃过贪多的亏。最开始我把能找到的竞赛题全都往里塞,联赛的、冬令营的、各个国家的、各种年代的,结果数据集膨胀到几万道,评测跑一轮成本高得离谱,出来的分数还特别难解释。后来我改成按来源分池管理,把题目按竞赛层级切成几个子集:省级联赛级别、国家级决赛级别、国际级竞赛级别。每个子集单独统计表现,不混在一起算总分。这样做的好处是,我能看到模型能力随着竞赛层级上升的衰减曲线,这条曲线比一个孤立的准确率数字有信息量得多。

难度分层是另一个让我反复调整的地方。竞赛题难度不是线性的,有些题看起来短小,实际需要非常精巧的构造,有些题篇幅很长,拆开看每一步都不难。我试过用“平均解题时间”来标难度,也试过用“步骤数”来标,都不太靠谱。现在我的做法是让几个有竞赛背景的人独立给每道题打一个主观难度分,取中位数,再结合该题在真实竞赛中的得分率做校准。这个过程很笨,但出来的分层结果至少我自己敢用。知识点覆盖上,我按代数、几何、数论、组合四大块做第一层划分,每块下面再按具体方法细分子类,比如几何下面再分纯几何综合、三角方法、解析方法、复数方法。分层做得越细,后面分析模型短板的时候才越有抓手。

2.2 数据清洗、答案验证与多解多步推理标注

数据清洗听起来是个体力活,实际做起来才发现它直接关系到评测的可信度。我遇到过原始题目扫描件里有错别字导致题意变了的,遇到过答案栏印错数字的,还遇到过同一道题在不同年份的合集里表述略有出入的。最麻烦的一种情况是题目本身没问题,但流传的“标准答案”只给了一个最终数字,中间过程完全省略。这种题如果直接放进评测集,模型答对了你也不知道它是真推出来的还是蒙的。所以我现在每收一道题,都会尽量找到两个以上来源交叉验证,实在找不到的就标记为“低置信度”,在正式评测里单独处理。

答案验证这件事,比我想的复杂得多。计算题相对好办,最终结果是一个明确的数值或表达式,人工核验或者用符号计算工具辅助验证都可以。证明题就麻烦了,很多竞赛证明题的“答案”是一段完整的证明,可这段证明是否唯一、是否有更简洁的写法、模型给出的另一种证明是否等价,这些都没法简单比对。我目前的折中做法是,证明题标注两层:一层是“关键节点”,也就是证明链条上必须出现的几个核心论断;另一层是“可接受结论形式”,允许模型用不同的等价表述收尾。多解标注也是类似思路,一道题如果有几种典型解法,我会把每种解法的关键步骤分别标出来,评测时不要求模型匹配某一种特定路径,而是看它的推理能否覆盖任意一种路径的关键节点。

多步推理标注是我花时间最多的一块。竞赛题的推理链往往有主线和支线,主线是必须走的,支线是分类讨论时才会展开的分支。我最初试图把每一步都线性标出来,标了几十道题之后就放弃了,因为很多步骤之间的依赖关系不是线性的。现在我改成图结构标注:节点是关键推理步骤,边表示依赖关系,分情况讨论的节点会分叉。这种标注方式的工作量很大,但它让我后面设计过程指标时有了可对照的参照系。我得承认,目前只对一部分核心题目做了全图标注,大部分题还是只标了关键节点,这是一个还在推进中的工程。

2.3 题型任务化:计算题、证明题、组合题与开放构造题

把题目按题型任务化,是我整个数据集设计里最影响后续评测方式的一步。计算题的任务形式最直接,给定题干,要求输出最终结果,评测时做答案匹配或者数值等价判断。这类题在数据集里占比不低,它们对检验模型的基础运算和代数变形能力很有用,但单靠它们区分不出模型在高阶推理上的差异。我一般把计算题当作评测的“底噪层”,先看模型在这一层是不是稳定,如果不稳定,后面的证明题表现基本不用看了。

证明题的任务化设计让我纠结了很久。一种做法是让模型直接输出完整证明,评测时由人工或者辅助模型去检查关键节点是否出现。另一种做法是把证明拆成填空或者步骤排序的形式,降低输出自由度,便于自动评测。我两种都试过,现在倾向于混合使用:大部分证明题保留开放输出,但评分时重点看关键节点覆盖率;少量核心题目做成步骤级任务,用来做精细的误差定位。组合题的情况更特殊一些,很多组合题的核心难点在于构造一个满足条件的例子或者证明某个界是最优的。这类题我单独设计了一类任务格式,要求模型不仅给出结论,还要明确写出构造过程或者最优性论证的关键思路,评测时对构造部分做单独检查。

开放构造题是我最不敢掉以轻心的类型。这类题往往没有唯一答案,甚至答案的形式都很自由,模型可能给出一个完全合理但与参考答案不同的构造。我现在的处理方式是,为每道开放构造题预设一组“可接受性判据”,比如构造是否满足所有约束、是否覆盖了题目要求的规模、是否存在明显漏洞。判据由人工预先写好,评测时逐条核对。这种做法没法完全自动化,成本也高,但我觉得对于竞赛级评测来说,开放构造题恰恰是最能暴露模型真实推理水平的题型,不能因为难评就回避掉。

2.4 数据集质量评估与防泄漏、防污染机制

数据集质量评估这块,我现在的习惯是每隔一段时间就做一次“内部审计”。具体做法是从数据集里随机抽一批题,让几个不同背景的人独立做一遍,看他们的解答和标注是否一致。不一致的地方要么是题目表述有歧义,要么是标注本身有问题,这两种情况都会被我拎出来修正。我还专门统计过一类指标,就是同一道题在不同来源之间的表述差异率,这个数字偏高的话说明我的清洗流程还有漏洞。审计的频率不用太高,但每次都能揪出一些问题,我觉得挺值。

防泄漏这件事,在竞赛题场景下比通用评测更棘手。很多竞赛题在网上流传极广,模型在预训练阶段很可能已经见过原题甚至见过解答。我目前的应对手段有几个:一是对题干做轻度扰动,比如改变变量名、调整数值、换一种等价表述,观察模型表现是否出现断崖式变化,如果变化很大,说明它可能是在依赖记忆而非推理;二是保留一批“新鲜题”,也就是近期竞赛中出现的、网上讨论还比较少的题目,作为对照集;三是在评测报告中明确区分“可能见过”和“不太可能见过”的题目子集,分开汇报结果。这些手段都不能完全杜绝泄漏,但至少能让评测结论更诚实一些。

防污染机制更多是流程层面的约束。我给自己定的规矩是,评测集的题目不进入任何训练数据管线,标注过程产生的中间文件也单独隔离存放。数据集版本更新时保留完整的变更日志,哪道题被修改过、为什么修改、修改前后是什么样,都记录在案。听起来有点繁琐,但我吃过一次亏:早期有一版数据集里混进了几道从训练语料里爬来的题,后来发现模型在那几道题上的表现异常好,排查了半天才定位到原因。从那以后我就把防污染当成一件必须较真的事情来做,哪怕慢一点,也比评测结果不可信要强。

做完数据集那套东西之后,我在很长一段时间里陷入了一种奇怪的焦虑:数据集搭好了,题也标注完了,可到底该怎么给模型打分,我脑子里其实没底。最早我只会看准确率,答对了就算对,答错了就算错,简单粗暴。后来有一道证明题让我彻底改了这个习惯——模型给了一个完整证明,每一步单独看都能说得通,但整条推理链在中间某处悄悄把结论当成条件用了,最后居然推到了正确的结果。如果只看最终答案,这道题它算过关了。我盯着那个证明看了十几分钟,越看越觉得这事不对劲,从那时候起我开始琢磨:光看结果到底够不够?

3.1 结果正确性指标:答案匹配、最终数值与证明有效性

结果正确性指标是我评测体系的第一道闸门,也是最容易实现、最容易被误用的那一个。答案匹配听起来简单,做起来其实需要分情况处理。计算题这类有明确最终结果的题,我一般用结构化匹配加数值等价判断,比如模型输出的是分数形式而答案是小数形式,只要数值在允许误差范围内就算正确。表达式类的题目更麻烦一些,我试过用符号计算库做等价化简,大部分情况能处理,但遇到三角恒等式或者复杂根式的时候,化简工具本身也会卡住。我现在的做法是自动判断为主,人工复核兜底,遇到自动判断拿不准的就标记出来集中处理。

最终数值指标有一个隐蔽的坑,就是模型可能通过枚举或者猜测撞上正确答案。竞赛题里有不少题答案是个不大的整数,模型如果一直在那试,碰巧答对的概率不可忽略。我专门做过一次统计,在某一批数论题上,模型最终答案正确但推理过程完全无关的比例大概在一成左右。这个数字让我在后来的评测里加了一条规矩:纯数值题如果模型答对了,我会额外看它有没有给出至少关键步骤,没有的话这道题记为“答案正确但过程存疑”,单独统计。证明有效性这件事更难,我目前用关键节点覆盖率来做代理指标,也就是看模型输出的证明里是否包含了标注的那些核心论断,覆盖率达到一定比例才算通过。这个方法当然不完美,它没法判断证明的整体逻辑是否自洽,但比我一开始只看最后那句话要靠谱得多。

3.2 推理过程指标:步骤一致性、逻辑严谨性与可验证性

过程指标是我花心思最多的一块,也最容易引起争议。步骤一致性指的是模型输出的推理链和它自己的结论之间是否一致,有些模型会在中间某一步说“由此可得某某结论”,你仔细一看那个结论根本不是前面推出来的,它只是想把故事讲圆。我现在的检测方式是,把模型的推理链拆成一段一段的陈述,每一段单独判断是否能由前面的陈述加题目条件推出,判断由另一个独立的评审模型或者人工来做。这个做法成本不低,但能抓出一批“结论对过程乱”的案例,这类案例在只看答案的评测里是完全隐形的。

逻辑严谨性指标更偏定性一些,我主要看几件事:有没有循环论证,有没有把特殊情况的结论推广到一般情况,有没有遗漏分类讨论的分支。这几件事在竞赛题里特别常见,模型在组合题上尤其容易犯漏分支的毛病。我遇到过一个典型案例,题目要求对参数分情况讨论,模型只讨论了两种情况,第三种情况悄悄跳过了,最后结论恰好和参考答案一致。这种题如果只看答案就是满分,但在我的过程评分里是要扣分的。可验证性是我最近才加进来的维度,简单说就是看模型给出的推导能不能被独立复现——我把模型输出的某几个中间结论单独拿出来,让另一个模型或者人从已知条件出发去验证,能验证通过的比例越高,这个过程就越可验证。这个指标还在试运行阶段,我觉得方向是对的,但具体怎么设计得更稳定,还在摸索。

3.3 效率与鲁棒性指标:token消耗、尝试次数与扰动稳定性

效率指标一开始我觉得不太重要,数学题嘛,答对就行,管它花多少token。后来跑了一批大规模评测之后我改了看法,因为有些模型在竞赛题上表现不稳定,同一个题换个提问方式就要多花好几倍token反复试探,这种不稳定性本身就是一种能力缺陷。我现在记录每道题的token消耗,分输入和输出两部分,再算一个“有效推理密度”,也就是最终被认定为有效步骤的部分占输出总长度的比例。这个比例低的模型,往往是在绕圈子或者重复自己。

尝试次数这个指标我是从人类竞赛选手那里借来的思路。真正的高手做一道题,往往一次就沿着正确方向推进,过程中会有小调整但不会推倒重来。模型如果在一道题上反复推翻自己的中间结论,哪怕最后答对了,我也倾向于给它打个折扣。我的做法是让模型在单次对话里完整输出推理过程,然后数它中途出现“等等,我之前的做法有问题”这类自我纠正的次数。这个数字不是越低越好,偶尔一次纠正说明模型在自我检查,但频繁纠正往往意味着它在盲目搜索而不是在推理。扰动稳定性是我最近比较看重的一个维度,具体做法是对题干做无关紧要的改动,比如换一个字母表示变量、把数字调小一点但不改变题型,看模型的表现是否保持稳定。有些模型在原题上答得好好的,换个变量名就崩了,这说明它的表现可能建立在某种脆弱的表面匹配上。

3.4 评测协议设计:零样本少样本、工具调用与多评审机制

评测协议这块我走过不少弯路。最开始我所有题都用零样本方式测,后来发现有些模型在少样本提示下表现差异很大,同一道题给两个示例和不给示例,分数能差出十几个点。我现在的基本协议是主评测用零样本,同时保留一个少样本对照组,两组分开汇报。这样做的目的是把模型本身的推理能力和它对提示格式的敏感度分开来看。零样本强而少样本弱,说明模型可能不太会从示例里提取模式;反过来则说明模型需要额外的上下文线索才能进入状态,这两种情况对使用者来说意义完全不同。

工具调用这个变量我犹豫了很久要不要放进主协议里。竞赛题里有些计算量很大的题,人类选手也会借助计算器或者符号计算工具,模型如果能调用外部工具完成机械计算部分,把精力集中在推理上,这本身不算作弊。我现在的折中方案是设置两个评测轨道:纯推理轨道不允许任何工具调用,工具辅助轨道允许调用计算工具但要求模型明确写出每一步调用了什么、得到了什么中间结果。两条轨道的结果我都报,让读者自己判断。多评审机制是保证过程指标可信度的关键一环,我目前的配置是每道题至少两个独立评审,一个来自模型评审员,一个来自人工抽检,两边不一致的题目进入第三轮仲裁。这个流程跑起来确实慢,但我在早期只用一个评审员的时候吃过亏,同一个模型评审员对不同风格的证明有系统性偏好,导致某些推理路径被不公平地压低分数。多评审不能消除主观性,但至少能把主观性的影响摊薄一些。

说了这么多指标和协议,我越来越觉得评测这件事的核心矛盾在于:我们想要的是一种能刻画推理质量的度量,手上能用的却大多是对结果的近似。这中间的缝隙,就是我后面要专门讨论的误差来源和评测局限。

前面三章把数据集怎么搭、指标怎么定、协议怎么跑都聊了一遍,说实话那都是图纸上的事。真正把评测跑起来之后,我发现图纸和工地之间隔着十万八千里。这一章我想聊聊实际跑出来的结果长什么样,哪些模型让我意外,哪些错误反复出现,以及这套评测体系往后该往哪儿走。有些结论我到现在也不敢说死,毕竟评测这件事本身还在快速变化。

4.1 典型模型在竞赛题基准上的表现对比与误差归因

我手头跑过的那批模型,从闭源旗舰到开源中等规模都有,整体印象是分数分布比我想象中更分散。最高分和最低分之间差了将近四十个百分点,这个差距在通用数学题上要小得多。竞赛题像个筛子,把模型之间的能力差异筛得特别明显。有一类模型在代数计算题上表现很稳,步骤干净利落,但一碰到组合构造题就开始胡言乱语,给出的构造要么不满足题设条件,要么干脆重复了题目里已经排除的情况。另一类模型反过来,它在需要灵光一现的构造题上偶尔能给出让人眼前一亮的思路,可一到需要精确计算的多项式题就频繁算错符号,中间步骤看着都对,最后一步正负号搞反了。

误差归因这件事我做了好几轮,越做越觉得不能笼统地说“模型推理能力不行”。我把错误案例分了几类,占比最高的是“推理链中途断裂”,大概占到所有错误的三成多。这类错误的典型表现是模型在前面几步推得挺像回事,到中间突然跳到一个没有根据的结论上,后面的推导再从这个空中楼阁继续往下走。第二大类是“分类讨论遗漏”,在组合题和数论题里特别集中,模型往往只讨论了最明显的一两种情况就急着下结论。还有一类让我哭笑不得的错误是“阅读理解偏差”,题目里某个条件被模型理解成了另一个意思,后面整道题的推理方向就全歪了,这种错误在文字稍长的竞赛题上出现频率不低。

具体到题目类型上,差异就更明显了。纯计算类的竞赛题,头部模型的正确率能到七八成,中档模型也有五成左右。证明题的表现就惨淡得多,即便是最好的模型,在我那套关键节点覆盖率的指标下也只有四成出头能拿到“基本有效”的评级。组合题是最能拉开差距的题型,有些模型在这类题上的得分接近于零,不是它完全不会做,而是它给出的构造几乎从来不满足所有约束条件。我印象特别深的一道图论构造题,要求构造一个满足三个特定性质的图,有个模型洋洋洒洒写了一大段,最后画出来的图确实有它说的那些边,可节点数根本不对,它把题目里的节点数条件整个忽略了。这类错误说明模型在长约束条件下保持全局一致性的能力还很欠缺。

还有一件事值得单独说,就是模型在不同难度层级上的表现曲线。我把题目按难度分成三档,简单档上各模型差距不大,基本上都能做对七八成。中等档开始分化,头部模型还能维持在六成以上,中档模型掉到三成左右。到了最难的那一档,所有模型的正确率都断崖式下跌,最好的也就两成出头。这个曲线形状告诉我,竞赛题评测的区分度主要来自中高档题目,简单题大家都会做,难题大家都做不出,真正能看出模型水平差异的是中间那段。这也影响了我后来选题的策略,中等偏难的题目权重被我调高了。

4.2 评测结果对模型训练、数据构建与提示策略的反馈

跑完第一轮大规模评测之后,我拿着那份错误分析报告去跟做训练的朋友聊了一次,聊完他跟我说了句话让我记到现在:“你这些错误类型,有一半是我在数据里就能预判到的。”这句话点醒了我,评测结果不该只是排行榜上的数字,它得能往回反馈到训练和数据构建的环节里去。我后来专门整理了一份“高频错误模式清单”,比如“符号处理失误”“分类讨论不完整”“长条件约束丢失”这几类,交给数据团队让他们在构造训练数据的时候有针对性地补充对应类型的题目和解题过程。反馈了一圈之后,下一版模型在符号处理上的错误率确实降了一些,虽然降幅没有我期望的那么大。

数据构建这边得到的反馈更直接。我在评测里发现模型对“至少”“至多”“存在”“任意”这类量词的处理非常不稳定,同一道题把“存在”改成“任意”,模型的表现能差出二十个百分点。这说明训练数据里这类量词的用法可能不够丰富,或者模型没有学到量词对解题路径的决定性影响。后来我们在数据标注规范里加了一条,要求标注员在标注推理步骤时明确标出每一步用到了哪个量词条件。这个改动听起来很小,但它让训练数据里量词和推理步骤之间的对应关系变得显式了,模型学起来应该会更容易一些。

提示策略这边的反馈来得最快也最明显。我拿同一批题试过好几种提示格式,发现了一个挺有意思的现象:对于计算题,给模型一个“先写已知条件,再列计划,最后执行”的三段式提示模板,正确率能提高十来个点。可同样的模板用在证明题上,效果反而是负的,模型会机械地往模板里填内容,写出来的证明比不加模板还僵硬。这件事让我意识到提示策略不能一刀切,不同题型需要不同的引导方式。证明题可能更需要的是鼓励模型先探索再整理,而不是一上来就套结构。我现在在评测协议里已经把题型和提示模板的搭配作为一个独立变量在记录了,虽然数据还不够多,但趋势已经能看出来。

还有一个反馈回路是我最近才建立的,就是把评测中发现的“过程存疑但答案正确”的案例单独打包,送回训练环节做负样本。这类案例对模型来说特别有迷惑性,因为它答案对了,常规的训练信号会告诉它“这样做是对的”,可实际上过程有问题。我把这些案例标注成“答案正确但推理不可取”,让模型在训练时能区分开“碰巧对了”和“真的会做”。这个做法效果还在观察中,但我觉得方向是对的,评测不只是打分,它还得能生产出有价值的训练信号。

4.3 当前评测局限:数据饱和、评分主观性与证明自动验证难题

说到局限,我脑子里第一个蹦出来的就是数据饱和。竞赛题虽然年年有新的,但经典题库就那么多,公开的、高质量的、有详细解答的竞赛题翻来覆去就那么些。我手头的数据集跑了两轮之后就开始出现这个问题了,头部模型在公开题库上的分数已经逼近人类优秀选手的水平,可你换一套从来没公开过的新题上去,它的分数立马掉一大截。这说明什么?说明模型可能在训练数据里见过这些题,或者至少见过高度相似的题。数据污染这件事在竞赛题评测里特别难防,因为竞赛题的解法往往很独特,模型只要在预训练阶段瞄过一眼标准答案,它就能在评测里表现得像个天才。我现在能做的就是把新题严格隔离,评测前不公开、不泄露,可这只能管住我自己的数据集,管不住别的来源。整个领域需要一个持续更新的、防污染的竞赛题评测基准,单靠一两个团队做这件事远远不够。

评分主观性的问题我在第三章提过一嘴,这里想展开说说它到底有多棘手。结果正确性好歹有个客观标准,对就是对错就是错,虽然也有数值等价判断的麻烦,但总体可控。过程评分就完全是另一回事了。我试过让三个不同的评审模型给同一道证明题打分,三个分数分别是“基本有效”“部分有效”“无效”,我去看它们各自的理由,发现三个评审关注的点完全不一样。一个盯着关键节点覆盖率,一个盯着逻辑连接词用得对不对,还有一个在纠结证明风格像不像人类写的。这三套标准单独看都有道理,放在一起就没法比较了。人工评审也有类似的问题,我请过两位数学系的朋友帮忙评同一批证明,他们俩在七成左右的题目上意见一致,剩下三成里有些分歧大得让我怀疑他们看的是不是同一道题。评分主观性短期内消不掉,我能想到的缓解办法就是多评审加明确评分细则,细则写得越具体,评审之间的分歧就越小,但这又带来了新问题:细则太具体了,模型只要照着细则的关键词去凑就能拿高分,哪怕它的证明内核是空的。

证明自动验证这件事我寄予厚望但进展缓慢。理想情况下,模型输出的证明应该能被自动验证器逐步检查,每一步是否合法由机器判定,这样过程评分就完全客观了。现实是,现有的自动验证工具对自然语言书写的证明几乎无能为力,模型输出的是人话,不是形式化语言。我试过让模型先把证明翻译成Lean或者Coq能接受的格式,然后再跑自动验证,翻译这一步本身就错漏百出,模型经常把自然语言的模糊表述翻译成错误的形式化语句,验证器说“不通过”,你根本分不清是原证明有问题还是翻译出了问题。另一条路是用大模型来做证明步骤的自动检查,我试过让一个专门微调过的评审模型逐步验证推理链,它在简单步骤上还行,一到需要领域知识的步骤就开始胡判。有个案例让我印象很深,一个关于多项式的中间步骤用到了一个不太常见的恒等式,评审模型直接判了“无依据”,可那个恒等式是成立的,只是不那么有名。自动验证的路还很长,短期内的现实方案还是自动初筛加人工复核,把人工集中在机器拿不准的那些步骤上。

4.4 面向可信推理的评测体系演进与开放问题

往后看,我觉得评测体系最该演进的的方向是从“判对错”走向“判可信”。现在的评测很大程度上还是在回答“模型能不能做对这道题”,可信推理要求回答的是“模型的推理过程在多大程度上可以被信任”。这两个问题看着接近,实际上差得很远。一道题做对了,过程可能有一半步骤是蒙的;一道题做错了,过程可能大部分步骤都是合理的,只在最后一步算错。可信推理的评测得能区分这些情况,它需要比现在细得多的过程标注和比现在稳得多的过程判断。我目前能想到的切入点是“推理链可复现性”,就是让另一个独立的模型或者人在不看标准答案的情况下,仅根据模型输出的推理链去判断结论是否成立。如果推理链本身足够严谨,一个没做过这道题的人顺着读下来也应该能被说服。这个指标我还在设计阶段,但我觉得它比关键节点覆盖率更接近“可信”这个目标。

动态评测是我另一个看好的方向。静态题库的饱和问题短期内无解,那就换一种思路,让题目本身动起来。我最近在试的一个小规模实验是,用程序生成带参数的竞赛题,每次评测时随机抽一组参数,题目的结构不变但具体数值和条件组合在变。这样做的好处是模型没法靠背答案过关,它必须真的理解解法才能做对参数变化后的版本。坏处是题目生成的难度控制很麻烦,参数稍微变一下,题目可能从竞赛级掉到课后练习级,或者反过来变得无解。我试过一批参数化的数论题,生成器自己有时候都搞不清哪些参数组合下题目有解,还得人工回头筛一遍。这条路能走通,但需要题目生成和难度校准两边都做得足够扎实。

开放问题里我最想不通的一个是:评测和训练之间的反馈循环到底该多紧。理想状态下评测应该独立于训练,像一把公正的尺子,可现实是评测发现的问题需要反馈给训练去改进,训练改进了又需要新的评测来验证,这个循环转起来之后评测的独立性就很难保证。我见过一些团队为了让自己的模型在评测上好看,专门针对评测集的题型分布去调训练数据,调完之后分数确实上去了,可换个评测集又打回原形。这种过拟合评测集的现象在竞赛题领域特别危险,因为竞赛题的题型本来就有限,针对性调优的空间很大。我现在倾向于认为评测集和训练集之间需要一道防火墙,评测集的题目和答案不能以任何形式进入训练流程,评测结果只能以“错误类型统计”这种粗粒度的形式反馈回去,不能具体到某道题某一步。这道防火墙能不能在工业级训练流程里真正建起来,我没有把握,但至少在我自己的评测实践里,我会尽量守住这条线。

还有一个开放问题是评测结果的表达方式。现在的排行榜文化把复杂的评测压缩成了一两个数字,排名高低一目了然,可数字背后的信息量被压没了。一个模型在竞赛题上拿了七十分,这七十分是怎么来的?它在哪些题型上强、哪些题型上弱、错误集中在哪个环节、过程质量和结果质量是否匹配,这些信息在排行榜上全看不见。我在想一种多维度的评测报告形式,不再给单一总分,而是给一个能力剖面图,把结果正确性、过程严谨性、鲁棒性、效率这几个维度分开呈现。这样做的问题是读者可能不买账,人天生喜欢比大小,剖面图看着热闹但没法直接排名。可我觉得如果评测的目标是理解模型能力而不是给模型排座次,剖面图比总分更有用。

最后说一个我最近在琢磨但还没动手的事:竞赛题评测能不能引入人类选手作为参照系。现在所有的评测指标都是绝对指标,正确率百分之六十、覆盖率百分之七十,这些数字单独看没有参照点。如果我把同一批题给经过训练的竞赛选手做,记录他们的正确率、解题时间、尝试次数、推理链特征,那模型的得分就有了一个人类基准线可以对照。模型的正确率比人类选手低多少、在哪些题型上差距最大、推理风格和人类有什么不同,这些问题有了人类数据才能回答。这件事做起来成本很高,找选手、设计实验、控制变量都不容易,但我觉得它值得做,因为评测最终要回答的问题是“模型在数学竞赛这件事上到底到了什么水平”,没有人类参照,这个问题永远只能回答一半。

这章写到这里,回头看整本书聊的东西,从数据集到指标到实践分析,核心关切其实一直没变:我想知道模型在竞赛题上的表现到底意味着什么,哪些是真实能力,哪些是评测假象。这个问题没有一劳永逸的答案,评测体系得跟着模型一起进化,我能做的就是把这几年踩过的坑和想明白的道理记下来,给后面做这件事的人省点弯路。

赞0
踩0
☆收藏0
版权声明
文章版权声明:除非注明,否则均为ZBLOG原创文章,转载或复制请以超链接形式并注明出处。
分享到
chuanbook

链接已复制到剪贴板