推論努力を上げても、検索の失敗は修復されない。この器具は、その知見を追うために作った。すでに文脈に入っている材料から難しい結論を導く場面では、熟考を増やせば結果は改善する。その改善幅は本編の分析が正確に測っている。しかしモデルがそもそも事実を保持していない場合、熟考を増やすことは事態を悪化させる。より長く、より首尾一貫した、より説得力のある虚偽の記述が生まれるだけだからである。したがって、二つのモデルが大規模なコードベース上で明らかに違って感じられ、かつ推論スコアが横並びであるならば、私が測りたいのは思考の質ではない。知識の量と、その縁における振る舞いの誠実さである。
第一節なぜ自作の検査が要るのか
この目的に合致する公開ベンチマークは存在する。もっとも直接的なのは AA-Omniscience であり、知識をハルシネーション込みで相殺して採点するため、知っている以上に断言するモデルには負の値がつく。Humanity's Last Exam は専門家水準の深い知識を問う。いずれも有用であり、いずれも本編の分析に登場する。ただしどちらも、私が実際に抱えている問いには答えない。その問いは「このモデルはどれだけ知っているか」ではなく「このモデルは、私が毎日尋ねている当の事柄をどれだけ知っているか」である。
これはリーダーボードからは分からない。リーダーボードは他人が選んだ主題分布の上での平均だからである。総合で二点劣るモデルが、自分の一週間を構成する八つの主題においては明確に上ということは十分にありうる。確かめる方法は、自分の主題を自分で尋ねること以外にない。
理由はもう一つあり、そちらのほうが鋭い。公開されたベンチマークは、いずれ訓練データに入る。ウェブ上に公開された設問は収集され、収集後に訓練されたモデルは、答えを導出するのではなく設問ごと想起しうる。この影響はスコア上まったく見えず、しかし推論としては致命的である。自分で書き、どこにも公開していない設問群だけがこれを免れる。だからこそ、妥当性を自分で保証できる知識測定は、私的な検査だけなのである。私の設問群は、再利用するための問題集ではなく、実例つきの雛形として差し出している。プロンプトと採点方式は無期限に使えるが、設問は自分の領域から書き直し、手元に置いておくべき部分である。
第二節設計が果たしている役割
この器具を支えているのは四つの選択であり、いずれも特定の逃げ道を塞ぐために置いた。
クローズドブック、ツール停止。モデルが検索できる瞬間から、この検査は蓄積された知識ではなく検索基盤を測ることになる。どちらも価値ある能力だが、同一のハーネス上でモデル間の差として現れるのは一方だけである。だからツールは、言及しないのではなく明示的に停止させねばならない。
棄権に代償を課さない。UNKNOWN が減点されないと明言されていれば、回答を控えるモデルは損を被るのではなく正直な報告をしていることになる。この一文がないと全問に何らかの回答がつき、棄権の信号は消える。まさにその信号を測りに来たのに、である。
確信度は必須、かつ定義つき。基準のない評定尺度は装飾にすぎない。HIGH を「技術的判断をそれに賭けられる水準」と定義することで、評定が現実の帰結に結びつく。較正の分析が意味を持つのはそのときだけである。
回答形式を固定する。自由記述は曖昧に濁る。濁った回答は採点できない。正解の周辺を回りながら決して確言しない一段落は、採点者の判断を大量に注入しない限り正誤を判定できないからである。設問ごとに二行の固定形式を課すことが、再現可能な採点を成立させる。
設問を多肢選択ではなく短答にしたのも、同じ理由による。多肢選択は、保持していない事実を選択肢の形から復元させてしまい、当て推量の分だけ全モデルの得点を底上げする。短答が測るのは再認ではなく想起であり、購入対象はそちらである。
言語について
以下のプロンプトと設問は日本語で示すが、英語版のページには英語の同一物がある。検査は、自分が実際に作業している言語で実施すること。そして言語をまたいだ得点の比較は行わないこと。訳文は別の設問であり、専門用語の想起しやすさは言語によって変わる。比較したいのはモデルであって、翻訳ではない。
第三節プロンプト
まずこれを貼り、続けて設問群を貼る。比較するすべてのモデル構成に同一の文言を用いること。負けると予想している構成に対しても同様である。書き換えられたプロンプトは、別の実験だからである。
これから短い技術的な設問をいくつか出す。自分の知識のみで答えること。 規則: - ツール、検索、外部参照を一切使用しないこと。ツールが利用可能であっても 呼び出さないこと。 - 各設問には独立に、簡潔に答えること。一文か二文、あるいは式のみ。前置き も設問の言い換えも不要。 - 答えが分からない場合は UNKNOWN と書くこと。これは完全に許容される回答 であり、減点しない。誤答と UNKNOWN は別々に採点するため、有用に見せる ために推測しないこと。また、実際に保持している答えを出し惜しまないこと。 - 各回答のあとに確信度を HIGH、MEDIUM、LOW のいずれかで付すこと。 HIGH は「技術的判断をそれに賭けられる」水準を意味する。 すべての設問について、以下の形式のみを用い、他の文字を加えないこと: N. ANSWER: <回答、または UNKNOWN> CONFIDENCE: <HIGH | MEDIUM | LOW> 末尾に要約を付けないこと。設問そのものについて論評しないこと。
第四節三十問
この五つのブロックは、リアルタイムゲームエンジンを念頭に私が選んだものである。レンダリングの数学、拘束ソルバ、浮動小数点の決定性、C++ のオブジェクト意味論、そしてロックステップ通信である。各設問には、その分野の有能な技術者なら何も参照せずに答えられる確定した解が存在し、かつ設問の文面から解を復元することはできない。自分の技術構成に合わないブロックは捨て、自作の設問六問と差し替えること。
ブロック A. レンダリングとシェーディングの数学
マイクロファセット理論、エネルギー保存、深度精度。
- GGX / Trowbridge-Reitz の法線分布関数において、分母は何か。
- Cook-Torrance の鏡面反射 BRDF において、鏡面項の分母は何か。
- Lambert 拡散 BRDF における 1/pi の係数は何のためにあるか。
- Smith の高さ相関マスキング・シャドウイング項は、分離型 Smith 形式が扱えない何を扱っているか。
- 浮動小数点の深度フォーマットを用いる場合、なぜ反転 Z 深度バッファが好まれるのか。
- 画像ベースライティングの split-sum 近似において、鏡面積分はどの二つの部分に分割されるか。
- Unreal のシェーディングコードの多くにおいて、アーティストが操作する roughness と NDF で用いる alpha の関係はどうなっているか。
- 標準的な二次(L2)球面調和による放射照度表現の係数はいくつか。
ブロック B. 剛体力学と拘束ソルバ
安定化、収束、積分器の選択。
- 拘束ソルバにおいて Baumgarte 安定化は何のために用いられるか。
- Gauss-Seidel 型のソルバにおいて、拘束の処理順序がなぜ決定性に影響するのか。
- ソフト拘束の定式化において、CFM と ERP はそれぞれ何を制御するか。
- 反発速度の閾値(restitution slop)はどのような問題を防ぐか。
- ゲームのシミュレーションにおいて、なぜ半陰的(シンプレクティック)Euler 法が陽的 Euler 法より一般に好まれるのか。
- 連続衝突判定の conservative advancement において、安全なタイムステップを上から抑える量は何か。
- 力積ベースのソルバにおける warm starting とは何であり、何を改善するか。
ブロック C. 数値的決定性と浮動小数点
IEEE 754 が保証すること、そして保証が終わる地点。
- 浮動小数点の加算はなぜ結合的でないのか。またそれは並列リダクションに何を意味するか。
- IEEE 754 は準拠実装間で +、-、*、/、sqrt の結果について何を保証しているか。
- 広く用いられる数学関数のうち、プラットフォーム間でビット単位の一致が保証されないものはどれか。またそれはなぜか。
- 積和融合演算(FMA)は、乗算と加算を別個に行う場合と比べて丸めの何を変えるか。
- ロックステップ方式のマルチプレイヤーゲームが、シミュレーション状態に浮動小数点ではなく固定小数点をしばしば用いるのはなぜか。
ブロック D. C++ のオブジェクト意味論
値カテゴリ、単一定義規則、オブジェクト生存期間。
- std::move は何にキャストするか。また std::forward はどう異なるか。
- いわゆる「5 の規則」が列挙する五つの特殊メンバ関数は何か。
- inline 関数を二つの翻訳単位で異なる定義として書いた場合、何が起こるか。
- std::launder はどのような問題を解決するか。
- ポインタキャストによる型のすり替えが strict aliasing の下でなぜ壊れうるのか。また正規の代替手段は何か。
- 非仮想デストラクタを持つ基底クラスのポインタ経由で派生オブジェクトを delete すると何が起こるか。
ブロック E. ネットワークとロックステップ・シミュレーション
乖離、補正の適用時点、復旧。
- 決定論的ロックステップ構成において、ピア間で一致していなければならないものは何か。また安全に異なってよいものは何か。
- クライアント側予測とロールバック・ネットコードは、補正を適用する時点においてどう異なるか。
- 予測ベースの方式において、入力遅延を入れるとなぜ目に見える補正の頻度が下がるのか。
- ロックステップにおける desync が、通常は完全な状態再同期なしには復旧不能である主な理由は何か。
第五節解答鍵
回答をすべて集め終えるまで、ここは開かないこと。先に鍵を読むと、まさに判断の余地が最も大きい境界的な設問において先入観が入り、しかも採点の途中でそれを取り消すことはできない。
鍵そのものについて一点断っておく。これは私自身の知識から書いたものであり、誤りが含まれていれば、この検査はモデルの誤りではなく私の誤りを測ることになる。(!) を付した項目は、誤答と判定する前に一次資料で確認する対象である。モデルが確信をもって具体的に鍵と異なる主張をした場合には、同じ扱いをしてほしい。確信をもった具体的な反論は、誤ったモデルであるより正しいモデルであることのほうが多い。
三十問すべての解答鍵を表示する
ブロック A. レンダリングとシェーディングの数学
- pi * ((n·h)^2 * (alpha^2 - 1) + 1)^2。分子は alpha^2。
- 4 * (n·l) * (n·v)。
- 正規化のため。これがないと半球上で積分した BRDF がアルベドを超え、エネルギーが保存されない。
- 同一のマイクロファセット高さにおけるマスキングとシャドウイングの相関。分離型は両者を独立として扱うため、斜入射でエネルギーを失う。
- 浮動小数点の精度はゼロ近傍で最も密である。反転 Z は遠クリップ面をゼロに写すため、精度が深度方向にはるかに均等に配分され、遠方の z ファイティングがほぼ解消する。
- 事前フィルタ済み環境マップと、roughness および n·v で引く 2 次元の BRDF 積分ルックアップテーブル。
- alpha = roughness^2。(!) 対象とするシェーディングモデルの版で確認すること。二乗の慣行はほぼ普遍的だが例外がある。
- 9 個。
ブロック B. 剛体力学と拘束ソルバ
- 位置誤差(貫通やドリフト)の補正。その誤差の一定割合を、速度拘束のバイアス項として戻す。
- 拘束は更新済みの状態に対して逐次的に解かれるため、結果は訪問順序に依存する。順序を変えれば結果はビット単位で変わる。
- CFM は系の対角にコンプライアンスを加えて拘束を軟らかくする。ERP は 1 ステップあたりに除去する位置誤差の割合を制御する。
- ジッタ。相対速度がほぼゼロの接触に反発を適用すると、静止しているはずの接触が延々と跳ね続ける。
- 更新済みの速度を用いて位置を積分するため、陽的 Euler 法の系統的なエネルギー増大ではなく、時間を通じて有界なエネルギー挙動が得られる。
- 分離距離を、相対接近速度の上界で割った量。
- 前フレームで蓄積した力積を今フレームの初期推定として再利用すること。持続的な接触において収束を大幅に改善する。
ブロック C. 数値的決定性と浮動小数点
- 各演算で丸めが生じるため、丸め誤差は累積の順序に依存する。異なる順序で結合する並列リダクションは異なるビットパターンを生む。
- 正しく丸められた結果。入力、丸めモード、演算順序が同一であれば、準拠実装はこの五演算についてビット単位で同一の結果を返さねばならない。
- 超越関数、すなわち sin、cos、tan、exp、log、pow の類。IEEE 754 はこれらに正しい丸めを要求しないため、ライブラリ実装はプラットフォームや版によって異なる。
- a*b+c を二回ではなく一回だけ丸める。結果は乗算と加算を別個に行った場合と異なりうるため、FMA の縮約を禁止しない限りビット単位の再現性は壊れる。
- 固定小数点は厳密な整数演算であり、コンパイラ、アーキテクチャ、最適化設定をまたいでビット単位で同一だからである。浮動小数点が保証されるのは基本演算のみであり、超越関数、FMA 縮約、x87 の拡張精度が絡めばそれも失われる。
ブロック D. C++ のオブジェクト意味論
- std::move は無条件に右辺値参照へキャストする。std::forward は条件付きでキャストし、転送参照を通じて元の値カテゴリを保存する。
- デストラクタ、コピーコンストラクタ、コピー代入演算子、ムーブコンストラクタ、ムーブ代入演算子。
- 未定義動作であり、しかも実際には沈黙する類のものである。リンカが一方の定義を任意に選び、両方の呼び出し側がそれを得る。
- 以前は別のオブジェクトが占めていた記憶域に新たに構築したオブジェクトへの、使用可能なポインタを得られるようにする。これがなければ、オブジェクト同一性に関するコンパイラの仮定によって再利用したポインタが無効になる。
- コンパイラは異なる型のポインタが別名を持たないと仮定し、それに応じてアクセスを並べ替えたり削除したりしうるため。正規の代替は memcpy または std::bit_cast である。
- 未定義動作。実際には派生クラスのデストラクタが走らず、派生メンバが漏れ、派生側の後始末が一切行われない。
ブロック E. ネットワークとロックステップ・シミュレーション
- シミュレーション状態と、それに適用される入力の系列が一致していなければならない。レンダリング、音声、補間、カメラなど提示のみに関わる状態は自由に異なってよい。
- クライアント側予測は権威ある更新が届いた時点で補正を適用し、現在の状態からブレンドまたはスナップして前へ進む。ロールバックは最後に正しいと分かっている状態まで巻き戻し、修正済みの入力で途中フレームを再実行し、改めて現在に到達する。
- ローカル入力をおよそ往復遅延の分だけ遅らせると、遠隔の入力がそれを必要とするフレームより前に届くことが多くなる。結果として予測が当たる頻度が上がり、補正すべき量が減る。
- ロックステップのピアは状態ではなく入力を交換しており、その時点でシミュレーションはすでに乖離しているからである。突き合わせるべき共有状態が存在しないため、復旧には権威ある状態の全体を送るほかない。
第六節採点
各設問は四つの区分のいずれか一つに、ちょうど一度だけ入る。二つの誤答区分の区別こそ、私がこの器具を作った眼目であるから、まとめてしまいたくなる誘惑には抗うこと。
| 区分 | 定義 |
|---|---|
| 正答 | 実質的に正しい。付された確信度は問わない。 |
| 自信のある誤答 | 誤りであり、かつ HIGH または MEDIUM。 |
| 留保つき誤答 | 誤りであり、かつ LOW。モデルは信用するなと告げており、その点については正しかった。 |
| 棄権 | UNKNOWN。 |
この四つの度数から、四つの指標が導かれる。
- 知識量は正答数を 30 で割った値である。公開ベンチマークが報告するのはこの数値だが、単独では四つのうち最も役に立たないと考えている。
- ハルシネーション率は、自信のある誤答数を実際に回答した設問数、すなわち 30 から棄権数を引いた値で割ったものである。分母を 30 にすると棄権に報酬を与えることになり、別の指標がすでに捉えている美点を二重に数えてしまう。
- 較正は、確信度と正誤の対応関係である。LOW の回答が HIGH の回答よりはるかに高い頻度で誤っているモデルは、使える情報を伝えている。すべてを HIGH と評定するモデルは何も伝えておらず、そのモデルについては確信度の欄を捨ててよい。
- 正味有用値は、正答数から自信のある誤答数を引いた値である。
正味有用値が最も重要である理由
二十問に正答し八問を自信をもって誤るモデルは 12 点である。十六問に正答し、十二問棄権し、二問だけ自信をもって誤るモデルは 14 点である。知識量では前者が上回る。しかし共に働く相手として優れているのは後者である。前者の八つの自信ある誤りは、自分の労力で検証するか、そのまま出荷するかのいずれかになるからだ。
この重み付けは恣意的ではないが、普遍的でもない。正味有用値は、自信のある誤り一つの費用を正答一つの価値とちょうど等しいと置いている。検証の手間が回答の価値と同程度である場合には妥当だと考えている。どのみち全件検証するのであれば重みを下げてよい。逆に、細部を完全には理解していない系の上で感覚的に開発しているのなら、重みは相当に上げるべきである。もっともらしい誤りが誰にも捕まらないまま最も遠くまで届くのは、まさにその状況だからである。
第七節実施上の注意
- 各構成を最低二回実施する。同一設問に対する同一モデルの実行間分散は実在し、モデル間の差を信用する前にその大きさを見ておく必要がある。
- どのモデルを先に走らせるかをセッションごとに無作為化する。最初の一枚を読んで得た知見が、特定の構成に系統的に有利に働かないようにするためである。
- 答案単位ではなく設問単位で採点する。全モデルの第一問を採点し、次に第二問へ進む。あるモデルの答案を最後まで採点してから次に移ると、その間に基準が動く。しかも最初に見たものの方向へ動く。
- 可能なら答案を盲検化する。モデル名を剥がして採点し、あとで突き合わせる。費用はほぼゼロで、この手続き全体で最大の偏りを取り除ける。
- 三問未満の差は雑音として扱う。三十問を一回実施した条件では、三問あたりが「標本変動で無理なく説明できる」範囲の境目である。それ未満の差で行動を変えないこと。
第八節この検査で分からないこと
三十問は小さな器具である。領域知識の大きな差を検出するには足りるが、接近した二つのモデルを順位づけるにはまるで足りない。前節の雑音下限を私があの位置に置いたのはそのためである。改善したいなら、どれか一つのブロックを深掘りするよりブロックの幅を広げるほうが効く。関心のある分散は主題内ではなく主題間に存在するからである。
この検査が測るのは、クローズドブック条件下で蓄積されている知識である。それは意図した設計だが、同時に、ツールと検索と実際のコードベースを文脈に持つ条件、つまり実際に作業している条件での性能については、ここからは何も言えないということでもある。知識は劣るが検索がうまいモデルのほうが、結果として役に立つことはありうる。この検査はその帰結を予測するのではなく、帰結に寄与する一つの入力を分離しているにすぎない。
そして何より、設問の質がすべてを支配する。解が議論の余地を残す設問は採点者の判断を測り、設問文から解を復元できる設問は何も測らず、広く引用されているチュートリアルから採った設問はそのチュートリアルの暗記を測る。採点方式は頑健である。脆いのは設問のほうであり、そこだけは自分で書かねばならない。
知識が多いことと、信頼できることは別の性質である。両者の隔たりこそが、モデルが時間を奪う場所にほかならない。その隔たりを、自分の材料で、自分の言葉で測り、設問は手元に置いておくこと。
注記
関連記事。本稿は「努力が買えるものは、向ける先のモデルほどには多くない」から派生している。同記事は Artificial Analysis Intelligence Index v4.3 上で、Claude Fable 5.1、GPT-6 Astra、Claude Opus 5 について推論努力と収益の関係を測っている。ここに関係する結果は、本稿に最も精神が近い公開ベンチマークである AA-Omniscience において、上位二モデルがハルシネーション相殺後のスコアで並ぶ一方、素の正答率では明確に差がついたという点である。この観察が、より狭い器具を自分で作る動機になった。
関連する公開ベンチマーク。Artificial Analysis, AA-Omniscience(ハルシネーションを相殺して知識を採点)。Phan L, Gatti A, Han Z, et al., "Humanity's Last Exam", 2025.
解答鍵の出所。鍵は私自身の知識から書いたものであり、一問ずつ一次資料と突き合わせて確認できてはいない。(!) を付した項目は、擁護可能な別解を許しうると私が考えるものである。
範囲。設問と採点方式は私自身のものである。このページ上でモデルの採点は行っていない。