今回は、どのモデルに渡すかを決める時点の話です。前回は「いつ止めるか」でしたが、今回は「誰に渡すか」になります。⚠️ 先に、題を否定しておきます。安いモデルは、使うべきです。私も使っています。⭐⭐ やめたのは、一番安いのを「既定」にすることのほうです。
⚠️ もう 1 つ断っておきます。この回にもモデルの名前も、価格も、性能の数字も出てきません。半年で古くなるものは、この連載では書かないと決めています。比べるものは「高い側」と「安い側」とだけ呼びます。⭐ そのかわり、倍率は全部出します。あなたの手元の単価を掛ければ、そのまま判断に使えるはずです。
⭐⭐ そして白状します。私はこの検証で 2 度、「差が無い」と読み間違えました。どちらも数字は正しく、読み方が間違っていました。⚠️⚠️ 2 度とも、指摘を受けて初めて気づきました。そのままなら「杞憂でした」と書いていたはずです。今回はその 2 回も含めて書きます。
一つ思い出してみてください。あなたが安いモデルに任せた仕事は、本当に安く終わりましたか。 ⚠️ やり直しの回数まで、数えたうえで言えますか。
CC BY 4.0
予測から始めました —— 「安いほうは、見逃しが増えるはず」
最初に立てた予測はこうです。
安いモデルにテストを書かせると、テストは書けるが、見逃しが増える。
⭐ 題材にテストを選んだのには理由があります。テストは、失敗が緑で隠れる唯一の成果物だからです。実装のバグはいつかどこかで落ちますが、テストの見逃しは何も言いません。「テストを書かせた」は緑で完了に見え、請求は後から来ます。
物差しは、過去に実物へ入れて、実物の検査が実際に落とした変異 8 種を当て直したものにしました。⚠️⚠️ この実験のために変異を書いてはいけません。書いた瞬間、見逃し率は書き方ひとつで 0% にも 100% にもなります。
⭐ 比べる相手も置きました。同じ対象に、人(私)が書いた既存のテストです。⚠️ そちらは 8 種のうち 6 種しか落としません。天井は満点ではありません。
条件は 2 つだけです。モデル(高い側 / 安い側)と、範囲(call 1 メソッドに絞る / 「必要だと思うテストを書いて」だけ)。⚠️ 観点は 1 つも渡していません。
1 回目 —— 安い側は、半分が走りませんでした
会話を引き継がない作業者を 12 体そろえて書かせ、変異を入れる前に、まず素のまま走らせました。
| 走った体 | 走った体だけの検出(8 種のうち何種を落としたか。⚠️ 多いほうが良い) | |
|---|---|---|
| 高い側 | 6 / 6 | 3.33 / 8 |
| ⚠️ 安い側 | 2 / 6 | 3.00 / 8 |
⚠️ 走らなかった 4 体の中身は、存在しないアサーションを呼ぶ・辞書の行を重複させるといった壊れ方でした。⭐ どれも、走らせた瞬間に分かります。
⭐ そこで私は、走らなかった 4 体を「見逃しとは別枠」として、検出の集計から外しました。理屈も一応ありました —— 走らないテストは、その場で気づけて、高いほうへ切り替えられます。
⚠️⚠️ これが 1 つ目の間違いです。
間違い 1 —— 走らなかったテストを、母数から落としていました
外した結果、残った安い側は 2 体だけです。その 2 体の平均を「安い側の実力」として、高い側 6 体と並べていました。
⚠️⚠️⚠️ 走らなかったものを母数から落とすと、いちばん危ない側が消えます。
⭐ 直し方は簡単でした。現実と同じように差し戻したのです。エラーの出力だけを返して「直してください」と送る。⚠️ 何が悪いかは言いません(言えば、それは物差しを渡すことになります)。
⭐⭐ 差し戻しを重ねて、12 体とも緑にしました。そのうえで数え直すと、こうなりました。
| 範囲を絞る | 絞らない | |
|---|---|---|
| 高い側 | 3.33 / 8 | 3.33 / 8 |
| 安い側 | 3.33 / 8 | 2.33 / 8 |
⭐⭐ 範囲を絞れば、安い側は高い側と同点です。私はここで、こう書こうとしました ——「安いモデルで増えるのは、その場で気づける失敗のほうです。見逃しは増えません。」
⚠️⚠️ これも間違いでした。
間違い 2 —— 物差しに、天井がありました
8 項目のうち 3 項目は、12 体とも 0 でした。⚠️ 人が書いた既存のテストは、その 3 つを落とします。
⭐ 3 つを並べてみると、共通点がありました。どれも「材料か測り方を、先に自分で用意しないと書けない」項目です。
- 表の中でいちばん長い見出し語を、自分で辞書に入れる
- 同じ表記に読みを 2 通り持たせる
- 戻り値ではなく、問い合わせの本数を数える
⚠️⚠️ 課題は、そんなことを一言も言っていませんでした。「単体テストを書いてください」としか書いていない。⭐ つまり 12 体とも 0 だったのは、書けなかったからではなく、課題がそこを指していなかったからかもしれない。
そこで、課題に 1 段落だけ足しました。
setupで作る辞書に現象が入っていなければ、そのテストは何も見ていません。 見たい振る舞いが出せるように、辞書のほうを組み立ててください。 戻り値を見るだけでは分からない振る舞いもあります。そういうものは、測り方のほうを用意してください。
⚠️ 8 項目はどれも名指ししていません。言っているのはやり方だけです。⚠️⚠️ そして両方の条件に、1 バイトも同じだけ渡しました(条件の差を増やしてしまうと、測っているものが変わります)。
天井が外れたら、結論がひっくり返りました
もう一度 12 体に書かせました。3 項目とも動きました。
| 1 回目(天井あり) | ⭐ 2 回目(天井なし) | |
|---|---|---|
| 高い側 | 3.33 / 8 | 5.00 / 8 |
| 安い側 | 2.83 / 8 | 2.83 / 8 |
| 高い側・範囲を絞る | 3.33 / 8 | 5.00 / 8 |
| ⚠️⚠️ 安い側・範囲を絞る | 3.33 / 8(同点) | 3.00 / 8(同点ではない) |
⭐⭐⭐ 天井を外すと、高い側だけが伸びました。安い側は 2.83 のまま動きません。
⚠️⚠️ 「絞れば同点」は、両方が簡単な項目しか取れず、そこで並んでいただけでした。
⚠️ ついでに、範囲の絞り方は見逃しには効きませんでした(高い側は 5.00 と 5.00 で差 0、安い側は 3.00 と 2.67)。⭐ 1 回目で範囲が効いていたのは「そもそも走るか」のほうで、見逃しの側ではありません。
⚠️⚠️ 最初の予測は当たっていました。ただし、当たっていると分かるまでに、母数の落とし方と物差しの天井を 2 つとも直す必要がありました。
差し戻しは、テストを消させます
差し戻しの回数は、高い側が 2 回の実験とも 0 回、安い側は 1 回目が 6 回・2 回目が 10 回でした。⭐ ここまでは想像どおりです。
⚠️⚠️⚠️ 想像していなかったのは、直し方のほうです。「実装は正しい。テストを直してください」と送ると、返ってきた直しのうち 3 件は、赤いテストを消したものでした。
- 「上限ちょうどは通す」という 1 件を、削除
- 全角の正規化を見る 1 件を、削除
- 重複した辞書の行を消さず、例外だけを飲む書き方に変更
⭐ どれも緑になります。⚠️⚠️ そして、消えた 1 件はそのまま見逃しになります。
⚠️⚠️⚠️ 「実装は正しい」と言って差し戻すと、直すより消すほうへ倒れます。
⚠️ これはモデルの話ではなく、差し戻し方の話です。⭐ ただし、差し戻しが要ったのは安い側だけでした。だから結果としては、モデルの側に効いています。
原理: 安いかどうかは「単価の比 × 量の比」で決まります
⭐ ここまでの数を、判断に使える形へ畳みます。1 回の応答の値段ではなく、1 つの仕事が終わるまでの総額で見ます。
同じ課題で、安い側が高い側の何倍を使ったかです。
| 数えたもの | 範囲を絞る | 絞らない | 全体 |
|---|---|---|---|
| 初めて読ませた量 | 1.64 倍 | 1.24 倍 | 1.48 倍 |
| ⭐ 使い回せた量 | 9.71 倍 | 2.62 倍 | 5.29 倍 |
| 書いた量 | 0.26 倍 | 0.38 倍 | 0.31 倍 |
| 手番(差し戻し込み) | 3.33 倍 | 2.00 倍 | 2.67 倍 |
⚠️⚠️ 安い側は、単価が安いだけではありません。量そのものが多いのです。やり直すたびに会話が伸び、伸びたぶんが次の手番でもう一度流れます。
⭐⭐ 使い回した部分は安く課金されますが、ゼロではありません。ここを 0 と見なすと、リトライは「ほぼタダ」に見えます。⚠️ 5.29 倍のものを 0 と数えれば、どんな結論でも作れます。
⭐ 書いた量だけは安い側のほうが少ない(0.31 倍)ので、出力の重い仕事なら向きが変わります。
⭐⭐⭐ 値段は「単価の比 × 量の比」。単価の比はカタログに書いてありますが、量の比は測らないと分かりません。
⚠️⚠️ だから「一番安いから既定」は、片方だけを見た判断です。⭐ 同じ理由で「一番高いから既定」も片方だけです。既定を置かず、用途ごとに 2 つとも数えます。
⚠️ 前作で、私は翻訳の用途では安い側を使うと書きました。その判断はいまも変えていません。あの用途では、安い側のほうが手数まで少なかったからです。⭐ 今回の結果は、それを打ち消しません。打ち消さないことこそが要点で、用途が変われば向きも変わるというだけです。
検証手順: 単価の比と、量の比を、別々に数える
前提
- 同じ課題を、2 つのモデルへ同じ材料で渡せること。⚠️ 材料が 1 バイトでも違うと、モデルの差ではなく材料の差を測ります
- 合否が機械で出る物差しがあること。⚠️⚠️ 人が読んで採点すると、測る回数が費用になって続きません
- 使ったトークンが、新しく読ませた量・使い回した量・書いた量に分けて残ること。⚠️ 分かれていないなら、この手順の後半は使えません
所要時間: 半日(物差しが既にある場合)
手順
- 物差しにする変異を、過去に実物へ入れて実物の検査が落としたものから採ります。⚠️⚠️ この実験のために書いてはいけません
- 人が書いた既存のテストを、同じ物差しに掛けます。⭐ これが天井です。⚠️ 満点なら物差しが緩いので、変異を足してください
- 同じ課題を 2 つのモデル × 2 つの範囲 × 3 回渡し、書かせます。⚠️ 走らせるのはこちらで、書き手には走らせません
- 変異を入れない状態で全部を走らせます。⚠️⚠️ 赤い体を「集計から外す」のは禁止です。エラーの出力だけを返して差し戻し、全部が緑になるまで繰り返します
- 緑になったものへ、変異を 1 種ずつ当てて走らせます。⭐ 変異 1 種につき全員ぶんを 1 回で回せます
- 差し戻しの回数と、新しく読ませた量・使い回した量・書いた量を、モデルごとに合計します
- 手元の単価表を掛けて、完了までの総額を出します
合格条件(すべて満たすこと)
- 手順 2 で、人の書いたテストが落とせない変異が 1 つ以上ある(満点なら天井です)
- 手順 4 のあと、全部の体が緑である(1 体でも赤いまま数えると、いちばん危ない側が母数から消えます)
- 手順 5 で、全員が 0 の項目が、全体の半分未満である。⚠️⚠️ 半分以上あるなら、課題がそこを指していません(材料と測り方を自分で用意する、と課題に書き足してください)
- 手順 6 で、使い回した量が 0 でない(0 なら分けて取れていません)
合格しなかったとき
- 人のテストが満点 —— ⚠️ 物差しが緩いか、実物の検査が落とした変異を採っていません
- 赤い体が緑にならない —— ⭐ そこが「高いほうへ切り替える」判断点です。⚠️ 回数を費用として記録してから切り替えます
- 全員が 0 の項目が半分以上 —— ⚠️⚠️ 天井です。課題の骨に 1 段落足して、両方の条件へ同じだけ渡し、測り直します
- 使い回した量が 0 —— ⚠️ 記録が分かれていません。分けて取れないなら、量の比は出さずに手番だけで判断します
後始末
- 一時的に置いたテストを消します。⚠️ 記録(トークンの内訳)は残します
- ⚠️ 結果は日付つきで残します。記録は増え続けるので、同じ道具を明日走らせると数が動きます
注意: この数字が言えないこと
⚠️⚠️ 1 つの枡が 3 体しかありません。向きだけを読んでください。5.00 と 2.83 の差は、順位としては読めますが、倍率として持ち出せる精度ではありません。
⚠️ 比べたのは 2 点だけです。高い側と安い側を 1 つずつ選んだので、「安いほど落ちる」という直線は、ここからは引けません。
⚠️⚠️ 8 項目のうち 1 つは、天井を外したあとに 12 体とも 0 になりました(⭐ 天井があったときは、12 体のうち 1 体が落としていた項目です)。人が書いたテストも、それは落とせません。⭐ つまりまだ天井が残っています。「どこまで差があるか」は、今回の物差しでは測り切れていません。
⚠️ 差し戻しは「実装が正しい」という前提で送っています。⭐⭐ その前提そのものが、テストを消させました。実務では実装が間違っていることもあるので、この差し戻し方をそのまま真似しないでください。
⚠️ 書き手にテストを走らせていません。⭐ 走らせられれば、安い側の赤は自分で気づけたはずです。「走らせない丸投げ」の数字だと思ってください。
⚠️⚠️ 最後に、題材のコードは、コメントがかなり厚いものでした。壊したときに何が起きるかまで、実装自身が書いています。⭐ コメントの薄いコードでは、両方とももっと落ちるはずです。そのまま持ち出せる数ではありません。
CC BY 4.0 はここまで
既定にしなくなったもの
- ⭐⭐ 「安いほうで足りるだろう」で渡すのをやめました。 ⚠️ それは予測です。単価の比はカタログにありますが、量の比は測らないと出ません
- ⭐ 走らなかった結果を、集計から外すのをやめました。 ⚠️⚠️ 外した瞬間、いちばん危ない側が母数から消えます。差し戻して、全部を緑にしてから数えます
- ⚠️ 「差が無い」と書く前に、物差しが動くかを見るようにしました。 ⭐ 全員が 0 の項目が半分あるなら、それは差が無いのではなく、測れていないだけです
- ⚠️⚠️ 「実装は正しい。テストを直せ」とだけ言って差し戻すのをやめました。 ⭐ 消して緑にする道が、そこに開いています
- ⭐ やめていないこともあります —— 用途ごとに安い側を選ぶことです。⚠️ 前作で選んだ用途は、いまも安い側のままです
安いモデルは安い、という感じは、たいてい正しく見えます。⚠️ 請求のうち、1 回ぶんの単価しか見ていないからです。 ⭐⭐ 見えないのは、やり直した回数と、そのたびに読み直された会話のほうでした。
次回は「最新モデルを使わない技術」。私は、新しいモデルが出た日に乗り換えるのをやめました。強いモデルでないと通らなかった仕事が、モデルを変えずに通るようになったからです。