モデル比較で平均点だけを置くのは危ない。同点でも、どの失敗を許容したかが真逆になる。採用判断には、設問群ごとの正解数を先に出すほうが効く。
9月1日に公開されたAi2のBenchMIRTは、100モデル・16ベンチマーク・3.4万超の設問を使い、総合点の内側にある能力を分けて見た。安全性ベンチマークとして扱われがちなBBQが推論寄りに出たり、WMDPでは推論が強いほど望ましいスコアが下がる関係も見つかっている。平均点は順位を作れる。でも失点の理由までは教えてくれない。
社内評価でMIRTをいきなり実装する必要はない。まずは設問に業務上の意味があるgroupを付け、モデルごとの通過数を並べる。障害解析、API契約、UI修正のように、リリース判断で混ぜたくない単位がよい。
平均点の下にある失敗の内訳。
from collections import defaultdict
results = [
{"model": "baseline", "group": "障害解析", "passed": x}
for x in [True, True, True, True]
] + [
{"model": "baseline", "group": "API契約", "passed": x}
for x in [True, True, False, False]
] + [
{"model": "candidate", "group": "障害解析", "passed": x}
for x in [True, True, False, False]
] + [
{"model": "candidate", "group": "API契約", "passed": x}
for x in [True, True, True, True]
]
counts = defaultdict(lambda: [0, 0])
for row in results:
key = row["model"], row["group"]
counts[key][0] += int(row["passed"])
counts[key][1] += 1
models = sorted({row["model"] for row in results})
groups = sorted({row["group"] for row in results})
print("model\t" + "\t".join(groups) + "\toverall")
for model in models:
cells = [counts[model, group] for group in groups]
ok, total = sum(x[0] for x in cells), sum(x[1] for x in cells)
print(model, *(f"{ok}/{n}" for ok, n in cells), f"{ok}/{total}", sep="\t")
Python 3.14.6で実行した出力はこうだった。どちらも6/8だが、baselineはAPI契約で2件落とし、candidateは障害解析で2件落とす。手元で最初にこの表を出したとき、同点という表示がかなり雑に見えた。
model API契約 障害解析 overall
baseline 2/4 4/4 6/8
candidate 4/4 2/4 6/8
groupを後付けすると恣意的になりやすい。評価を回す前に、各グループで「通れば何を任せられるか」を一文で決めておく。設問数も併記する。2/2を4/4より良く見せないためだ。
BenchMIRTの「10%の設問でも能力の比較像をおおむね保てた」という結果も、そのまま自分の評価数を十分とする根拠にはできない。対象の設問とモデルが違えば、残すべき設問も変わる。削る前には全件の表を一度作る。
おわりに
モデルの総合点は入口に置く。採用やルーティングを決める表には、業務別の通過数を足す。これだけで「高得点だが本番で外せない失敗」が見えるようになる。評価セットを増やす前に、まず今ある結果を分けて読む。そこが一番安い改善だった。
