2747 字
14 分钟
7B 循环两次就超过 480B?那个数是自己量的

6 月 16 日,arXiv 上挂出一篇叫 LoopCoder-v2 的论文(2606.18023),来自北航和 IQuest Research,结论很好卖:一个 7B 的代码模型只要在内部多循环一次(总共两次),SWE-bench Verified 就从 43.0 涨到 64.4,Multi-SWE 从 14.0 涨到 31.0,而再往上循环第三次、第四次反而会崩。

于是 HuggingFace 当周论文榜第二,播客做了,聚合站转了,推特上一片「效率碾压参数」。有人算了笔账说,1× 的训练资源换 loop× 的推理收益,还要什么 480B;也有人拿它当「少即是多」的证据,说这是给「无脑堆层」的当头一棒。

论文是真的,机制也是真的,而且是好活——我把 PDF 从头读到尾,越读越觉得它的分析部分值得尊重,因为它老老实实做了一件很多人不愿做的事:训了 1、2、3、4 循环四个从零开始的 7B,除了循环数别的全锁死,然后掰开揉碎去看每一循环里到底发生了什么。

问题出在另一个地方:让这篇论文出圈的那个数,也就是「7B 循环两次逼近 480B」的 64.4,是拿它自己的尺子量出来的,而那把尺子长什么样,论文全程没说。

先说 SWE-bench 是把什么尺子#

SWE-bench Verified 是 OpenAI 从原始 SWE-bench 里人工校验出来的 500 道题,每道题对应一个真实 GitHub 仓库的 issue,模型要生成一个能通过单元测试的 patch,听起来很客观——能修好就是能修好,pass@1 一个数,没得含糊。

但这个数极度依赖你给模型套的那层「脚手架」(scaffold / agent framework)。同一个模型,套 Agentless、套 SWE-agent 还是套 OpenHands,给它 5 次尝试还是 1 次,给它 128k 上下文还是 8k,分数能差出十几个点。OpenAI 自己在 o1 的报告里就写明,o1 用的是 Agentless,每题给 5 次生成。所以「SWE-bench Verified 64.4」这句话脱离了 harness 就只是半句,剩下半句是:用什么 harness、几次尝试、多少 token、单模型还是带 test-time compute——而这半句,恰好是所有 benchmark 表格里印在最底下、字号最小、没人看的那行星号小字。

那个 43 分从哪来的#

先别急着看 64.4,回头看它的对照组会更有意思:一个「非循环」的 7B baseline,考了 43.0。这是一个从零训练、结构上就是普通 transformer 的 7B,在 SWE-bench Verified 上拿了 43 分,而这个数本身就离谱得很。

离谱到什么程度呢?可以拿真实世界里专门为 SWE 任务训练的模型来做参照。Skywork-SWE-32B 喂了八千多条 SWE 轨迹,单次尝试、不带 verifier 也就 38.0%,得加上 test-time scaling(Best-of-8 + critic)才到 47.0%;同样 32B 的 SWE-agent-LM 是 40.2%;70B 还加了强化学习的 Llama3-SWE-RL 也不过 41.0%;至于 Qwen2.5-Coder-32B 这种没专门调过的,做 baseline 时只有 6.4%。换句话说,LoopCoder-v2 那个「什么都没循环」的 7B baseline,比人家专门做 SWE、体量还大四五倍的 32B 考得都高,跟 70B 的 RL 模型打平。

反过来的证据更扎心:论文自己的对照表里拿 Qwen2.5-Coder-7B-Instruct 当参照,它在同一张表上的 SWE-bench Verified 就是 0.0,一个标准配置的 7B 直接零分,而 LoopCoder-v2 却说自己那个非循环 7B baseline 有 43 分。再看标准化 harness 下的通用大模型,在 mini-SWE-agent 这套公开脚手架下,Llama 4 Maverick 大约 21%、Scout 大约 9%,而这些可都是几百 B 的模型。

那么问题就很简单:一个从零训练、结构上就是普通 transformer、论文里又没交代 agent 脚手架的 7B,凭什么在 SWE-bench Verified 上考 43 分?唯一说得通的解释,是它背后挂了一套很强的 agent 脚手架在扛活,可这套脚手架长什么样论文没写——我把正文和附录翻了一遍,关于 SWE-bench 的评测协议它只说了一句「按各 benchmark 的标准协议和指标」,至于标准协议到底是 Agentless、SWE-agent 还是 OpenHands,没有下文。

于是这里就有个绕不过去的坎:64.4 减 43.0 得到的那 21 分涨幅,只有在两个数用同一套(未知)脚手架跑出来时才算数;如果那套脚手架本身就能把 baseline 抬到 43,那 64.4 自然也是同一套脚手架抬上去的——两个数是一起可疑的,坏的不止一个。

每一列,都是各自的尺子#

再说横向比较那一栏。论文把自己的 64.4 摆进一列数字里:Qwen3-235B 是 45.2,Kimi-Dev-72B 是 60.4,Kimi-K2 是 69.2,Qwen3-Coder-480B 是 67.0,叙事一目了然——7B 循环两次,越过 72B,逼近 480B。

这些数单拎出来一个个都对。我去查了,Kimi-K2-Instruct-0905 官方卡片上写的就是 SWE-bench Verified 69.2 ± 0.63,五次独立跑的均值,Qwen3-Coder-480B 的 67.0、Qwen3-235B 的 45.2 也都能在公开资料里对上。真正的问题在于,它们根本不是用同一把尺子量的。

Moonshot 自己在 Kimi-K2 的卡片上就写得清清楚楚:除了 Terminal-Bench,所有分数都是用他们自研的评测 harness 跑的,这套 harness 从 SWE-agent 改来,钳制了 Bash 和 Edit 工具的上下文窗口、重写了 system prompt,每次跑之前还会把仓库里从目标 commit 不可达的 Git 对象全删掉,保证 agent 只看到那个时间点本该看到的代码;他们甚至特意标注,表里带星号的 baseline 数字是直接从对方官方报告或榜单里抄来的,并没有在同样条件下重新跑。再往下扒一层就更清楚了:Kimi-K2 单次尝试、不带 test-time compute 时是 65.8%,跑五次取均值是 69.2,要是开并行 test-time compute、采样多条再用内部打分模型挑一条还能到 71.6%——同一个模型、同一个 benchmark,三个数,全看你怎么跑,而论文引用的 69.2 恰好是其中比较好看的那个。

所以这一列数字说穿了就是:Kimi 用 Kimi 的 harness,Qwen 用 Qwen 的 OpenHands,LoopCoder-v2 用一套没说明的 harness,然后一起并排塞进一张表,表头叫「SWE-bench Verified」。这也不是我一个人的洁癖,另一篇做 SWE agent 的论文(SkyRL-Agent)就在自己的对照表底下写了句大白话,说不同工作用不同的 scaffold 和评测设置,这些数字未必能严格比较,还举例说某些在 Agentless 脚手架下训练的模型换到 ReAct 设置里连工具调用都跟不上,分数比原论文报的低一大截,只能「仅供参考」地列出来。

一张把各家自测数并排的表,看着是排行榜,其实是一堆各自量身定做的实验硬拼在一起——你可以用它讲一个「7B 吊打 480B」的故事,却没法用它下「7B 真的比 480B 强」的结论。(前沿模型的横向比较我之前也排过一版,那种表最耗时间的一步,恰恰就是先把口径对齐。)

好活是好活#

话说回来,公道话得说全:LoopCoder-v2 不是一篇烂论文,恰恰相反,它机制那半篇是这一批 looped transformer 工作里做得相当扎实的。

这篇真正的价值不在跑分——它第一次把「循环几次最划算」掰成了一个能测量的问题。它给的是一个 gain-cost 视角:多循环一次,表示会被「精炼」一下,这是收益;但 PLT 为了让循环能并行,用了 CLP(cross-loop position offset),做法是把上一循环的隐状态整体错开一位再喂进去,于是每个 token 依赖的是邻居而不是它自己,这样才并行得起来,代价是每个循环边界上都引入一个「位置错配」,这就是成本。论文用一堆内部指标(隐状态的有效秩、更新方向的夹角、注意力熵、输出分布的 KL)去量这两样东西,结论是第二次循环才是「生产性精炼」的主场、有效秩在这里见顶,而从第三次开始更新方向就反复横跳(夹角变负)、表示多样性反而塌了,偏偏那个位置错配的成本基本是固定的——收益在掉、成本不动,于是循环两次正好是甜点。

这个「非单调」的结论,也就是多循环不保证更好、甚至可能更差,本身既反直觉又有用,它顺带给出的诊断方法(盯着每循环的收益和那个固定的错配成本,收益低于成本就停)也是个正经工具,让「放模型循环」这件事有了一个「到此为止」的依据,而不用一味往上加。正因为机制这半篇是真东西,那个被拎去当标题的 64.4 才更可惜:一篇本可以老老实实讲「我们发现循环两次最优、并解释了为什么」的好论文,非得在对照表里塞一个「7B 逼近 480B」的格子,结果这个格子成了它出圈的全部。

出圈的是那个数,没人问的是那把尺#

6 月 16 日挂上 arXiv,很快就是 HuggingFace 当周论文榜第二、两百多个赞,播客做了,聚合站转了,推特上「效率碾压参数」「hard data 打脸堆层派」的评论刷了一屏。这一屏里当然也有人在往正经方向问,比如 HuggingFace 页面下面就有人追问,为什么表示多样性在第二循环之后掉得这么快、是不是纯粹因为位置错配——这是个冲着机制去的好问题;也有人泼冷水,说一个 7B 在 SWE-bench 上考 64.4,就像一台象棋机器靠两次暴力搜索开局库赢下比赛,benchmark 测的只是一个特定任务,真实软件工程要脏得多。

但「这个 64.4 到底是用什么 harness 跑的、那个 43 分的 baseline 是不是被做弱了」,这个最该问的问题,在那一屏转发里我几乎没看到;真正出圈的是「7B 超过 480B」这半句话,而印在最底下的那行星号小字,跟着论文一起被转到了地球另一端,没人展开。这其实也不怪转发的人——一张排行榜摆在那儿,谁会专门去读脚注,这本来就是 benchmark 表格这个体裁的设计:结论(一个格子)传播的速度,永远快过前提(那行小字)被人核对的速度。

一张榜单,叙事的成分远多于测量的成分。一个数要让你信,先得回答它是拿谁的尺子量的、量了几次、量的时候手有没有在旁边扶一把。LoopCoder-v2 的机制部分把该说的都说清楚了,可它那张对照表,偏偏把最该说的那把尺子给落下了。

7B 循环两次就超过 480B?那个数是自己量的
https://blog.lishuyu.app/posts/2026-06-30-loopcoder-v2-swe-bench-harness-critique/
作者
猫猫魔女
发布于
2026-06-30
许可协议
CC BY-NC-SA 4.0