~/blog/swe-bench-qwen36-failure-modes

DGX Spark · part 24

[SWE-bench] Qwen 3.6 35B 檢討考卷:155 題答錯,76% 是「找對檔案、改錯邏輯」

cat --toc

TL;DR

Qwen 3.6 35B-A3B FP8 在 SWE-bench Lite 解掉 145/300 = 48.33%。剩下 155 題裡 118 題(76%)是 wrong_logic — 找對檔案、寫出 patch、邏輯錯。同一套 scaffold 下 Gemma 4 26B 是 38.67%,差 9.66 個百分點。29 題落差去了哪裡?三條失敗類型的不同比例,是這篇的假設。

白話版:AI 怎麼修 GitHub 上的 bug,失敗的時候是怎麼錯

SWE-bench Lite 是一份 300 題的考卷,題目來自開源專案(django、sympy、matplotlib 這類)真實發生過的 bug。AI 拿到 bug 描述加上整個原始碼,要找出該改的檔案、寫出正確的 patch,跑測試通過才算解掉。

我們在 DGX Spark 上跑 Qwen 3.6 35B(中國 Qwen 的開源 AI)成功解掉 145 題,48.33%。對照組:Claude 3.7 Sonnet 配某些工具是 48%(幾個月前的紀錄)、Gemma 4 26B(Google 模型)用同一套 scaffold 是 38.67%。35B 的開源模型在地端電腦上,大概打到了幾個月前商用系統的水準。

剩下沒解的 155 題不是隨機分布。76% 都長得很像 — AI 找到對的檔案、寫出能套用的 patch,但邏輯細節錯(條件反向、變數沒定義、漏處理另一個分支)。剩下 14% 是只修了一半,10% 是花光步數還寫不出 patch。

這篇就是把這 155 題答錯的拆開來看,失敗的樣態長什麼樣。


29 題落差,不能用 active params 解釋

Part 18 給了三個模型在 SWE-bench Lite 的成績:

模型總參數啟動參數解掉同一套 scaffold
Gemma 4 E4B8B~1B50/300 = 16.67%
Gemma 4 26B-A4B26B4B116/300 = 38.67%
Qwen 3.6 35B-A3B35B3B145/300 = 48.33%

兩個 35B 級的模型 active params 一個 3B 一個 4B,差不多。但 Qwen 多解 29 題。

不能光憑這個推「Qwen 比較強」。Qwen 跟 Gemma 在總參數量(35B 對 26B)、架構(混合線性注意力加 MoE 對純 MoE)、訓練資料全都不同 — active params 只是一個維度。真正想知道 29 題去哪,得回頭看那 155 題答錯的是怎麼做的。


把 155 題未解分成三類

我把 155 個未解的軌跡丟回 Qwen 3.6 自己當分類器(這個做法本身就站不住腳,後面會回頭講),分成三類:

類別條件數量佔比
wrong_logic改對檔案、patch 能 apply、邏輯細節錯11876.1%
incomplete_patch改一半 — 處理了分支 A 但漏掉分支 B2113.5%
no_submission撞步數上限,沒交 patch1610.3%
wrong_logic       ████████████████████████████████ 76%
incomplete_patch  ██████ 14%
no_submission     █████ 10%

「找錯檔案」這一類失敗一個都沒有 — scaffold 的預算提示(「Steps 1-10 understand → 10-35 edit ONE file」)已經把這層擋掉,模型 100% 都找到該改的檔案。


三類錯法,三個範例

wrong_logic(76%)— 看起來對,跑起來錯

從 118 個抽三個典型:

1. astropy__astropy-14365 — 正則 flag 加了沒接到邏輯

Patch adds re.IGNORECASE to regex but does not handle case-insensitive command parsing correctly in logic.

模型加了 re.IGNORECASE,但實際比對邏輯沒跟著改成不分大小寫。flag 設了等於沒設。

2. django__django-11019 — 變數沒定義

Patch checks if element is in list_1 but list_1 is not defined in scope, causing NameError.

直接寫了個未定義的變數。Lint 抓得到,但 mini-swe-agent 沒跑 lint。

3. django__django-11283 — 條件反向

The patch logic is incorrect; it excludes permissions with the target content type instead of excluding those that already exist with the target content type.

文字看起來合理,但條件邏輯整個反了。光看 diff 看不出來,要跑測試才炸。

這類錯法的共通點:模型抓到問題大方向,patch 看起來也像那麼回事,就只有細節寫錯。

incomplete_patch(14%)— 改了一半就停

4. astropy__astropy-7746

Patch handles empty arrays in one branch but misses the other branch where ra_dec_order and sky conditions differ.

只 cover 一個 case,對稱的另一個漏掉。

5. django__django-11422

Patch adds watch_file for manage.py but misses watching other entry points like __main__.py or wsgi.py.

修了主要入口,沒看到還有其他 entry point。

這類錯法的共通點:模型修到一個明顯的點就收手,沒想到還有對稱或類似的情況也要處理。

no_submission(10%)— 跑光步數

6-8. django__django-11797django__django-13265django__django-15738

Hit 97-step limit without generating any patch. Hit 92-step limit without generating any patch. Hit 86-step limit without generating any patch.

這三題步數上限 100,模型探索完還寫不出 patch。

這類錯法的共通點:大型 codebase(django 是大宗)讓模型光探索就燒光步數。


失敗 repo 分布

155 個失敗來自 11 個 repo:

Repo失敗數佔總失敗
django4931.6%
sympy4529.0%
matplotlib159.7%
pytest-dev127.7%
scikit-learn95.8%
sphinx-doc95.8%
pydata42.6%
pylint-dev42.6%
astropy31.9%
pallets31.9%
mwaskom21.3%

django + sympy 佔 60.6%,跟 SWE-bench Lite 整體題目分布一致 — 不是 Qwen 3.6 在這兩個 repo 特別弱,單純它們本來就是大宗。


Gemma 4 26B 那 9.66% 落差,我猜去哪了

Gemma 4 26B 同一套 scaffold 拿 38.67%,比 Qwen 3.6 少 29 題。但 Gemma 4 那 184 題未解我們沒跑同樣的分類,所以下面是猜的(等驗證):

類別Qwen 3.6 比例Gemma 4 預期方向為什麼
no_submission10%應更高總參數量較小,大型 codebase 探索較吃力,更容易燒光步數
incomplete_patch14%應更高探索覆蓋面較窄,容易漏對稱 case
wrong_logic76%應較低因為更多題還沒走到 wrong_logic 這階段就先掛了

換句話說,「Qwen 的 patch 寫得比較對」可能是錯的直覺。更可能的真相是:Qwen 比 Gemma 多更多題能走到「寫 patch」這一步

要驗證 29 題到底去哪,只能對 Gemma 4 那 184 軌跡跑同一個分類器。


76% wrong_logic 的另一面:重試流程救得到嗎

Part 19(還在 draft)在試這個假設:既然 76% 都是 wrong_logic,把測試錯誤訊息丟回去讓模型再改一輪,理論上能撈回一部分

實驗結果:3 版提示 + 10 題,最後聯集救回 2/10。樣本太小,不能算 rate,但訊號出現了。

兩篇連起來看:

  • 這篇:48.33% 是 scaffold 單獨打到的天花板,76% 失敗都卡在「邏輯細節錯」
  • Part 19:把這 76% 餵回去重試 — 加在 scaffold 上面的動態那一層

最花時間的地方

讓 Qwen 3.6 自己分類自己的失敗,本身就是個會偏的做法。同一個模型評自己的軌跡,把邊界 case 標成 incomplete_patchwrong_logic 是比較好聽的講法,自我合理化的傾向避不掉。沒做交叉驗證(換 Claude 或 GPT 再跑一次對照),76% 這個值上下飄 5-10 個百分點都合理。

第二費神的是確認 scaffold 真的把「找錯檔案」那類失敗擋掉了。每個未解都進到「寫 patch」這一步,76% 的分母才有意義 — 不然「wrong_logic 76%」會變成「找對檔案的那部分裡有 76%」,完全是另一回事。所以一開始要先看軌跡,確認檔案定位都過了。

如果要做嚴謹版本,該補的:

  • 用獨立的強模型(Claude / GPT-5)重跑分類
  • 對 Gemma 4 26B 那 184 題未解跑同一個分類器
  • 算 Qwen 對 Gemma 在每個類別的差

可搬走的診斷方法

  1. 不要只看通過率,要看答錯的題目怎麼錯的。同樣 38.67%,可能一個是 76% wrong_logic + 10% no_submission,另一個是 50% no_submission + 20% wrong_logic — 兩個的天花板差很多,但只看通過率看不出來。
  2. wrong_logic 比例高,代表離成功很近。重試流程有機會撈得到一部分(Part 19 那條線就是在驗證這件事)。比例低反而是更基本的問題還沒解。
  3. 失敗分布要先對照題目分布。某個 repo 失敗多,不一定是模型不會處理那個 repo,可能那 repo 在 benchmark 本來就是大宗。算比例前先看整體分布,把 base rate 扣掉才看得出真信號。

通用原則

通過率是會飄的數字,失敗類別的比例才是真正能拿來判斷下一步該往哪走的線索。只看 38.67% 對 48.33%,你不知道下一步該優化什麼。看到 76% 是 wrong_logic,就知道重試流程值得試;看到 50% 是 no_submission,就知道得先解步數預算的問題。

開源 35B 在 GB10 上跑出 48.33%,對的 scaffold 把地板抬得比模型大小還高。一套對的 scaffold,通常比換更大的模型來得划算。


相關閱讀

常見問題

Qwen 3.6 35B 在 SWE-bench Lite 失敗的主要原因是什麼?
76% 是 `wrong_logic` — 模型找到正確的檔案、寫出能跑的 patch,只有邏輯細節錯(漏分支、scope 寫錯、條件反向)。14% 是 `incomplete_patch`(只修一半),10% 是 `no_submission`(撞步數上限沒交)。「找錯檔案」這類失敗一個都沒有 — scaffold 的預算提示已經把這層擋掉了。
Qwen 3.6 跟 Gemma 4 26B 用同一套 scaffold,為什麼 Qwen 高 9.66%?
scaffold 完全一樣(反引號協議 + edit-tool v2 + 預算提示),所以落差來自模型本身。但 Qwen 跟 Gemma 在總參數量(35B 對 26B)、架構(混合線性注意力加 MoE 對純 MoE)、訓練資料都不同,不是單一變數。真正該問的是「29 題的落差去了哪些失敗類別」,這要對 Gemma 4 那 184 題未解跑同一個分類器才能回答 — 還沒做。
76% `wrong_logic` 算好事還是壞事?
算好事。`wrong_logic` 表示模型找到對的檔案、能交出 patch — 已經比「找錯檔案」或「寫不出 patch」進步一大段。這也是為什麼 Part 19 試重試流程:把測試錯誤訊息丟回去讓模型修,理論上能撈回一部分。
Gemma 4 26B 的失敗模式是不是也 76% `wrong_logic`?
還沒跑。我們只有 116/300 解掉的數字,剩 184 題的軌跡沒套用同樣的分類器。我猜 Gemma 4 的失敗會更偏向 `no_submission` + `incomplete_patch`(總參數量小,大型 codebase 探索較吃力),但這只是猜測。