ファインチューニングとは?その前に分類ではないかを疑う

ファインチューニングとは、学習済みモデルに自社のデータを追加学習させて特定の用途に合わせることです。AIの出力を検査する仕組みを作るとき、最初は生成モデルを賢くしようとしていました。ところが必要だったのは生成ではなく分類でした。Macの16GBで常駐でき、高速に動くエンコーダー型を選び、100件を目視で作ってから6000件へ拡張しました。言い換えや翻訳は100%、抽象化された要約は70〜80%止まります。選定の理由とデータセットの作り方を書きます。
Total
0
Shares
ファインチューニングとは?大きいモデルを賢くする前に、それは分類ではないかを疑う

引っ越しのとき、電動ドライバーを買いました。棚を組むためです。

10本ほどネジを締めて、残りは手で回しました。 電動のほうが速いはずなのに、持ち替えて、先端を替えて、充電を確認する時間のほうが長かったからです。

ネジ1本には、手のドライバーのほうが速い。

道具の性能の話ではありませんでした。1回あたりの仕事が小さいときは、立ち上がりの重さが全部になるという話です。

先に一行だけ置きます。ファインチューニングとは、学習済みのモデルに自社のデータを追加学習させて、特定の用途に合わせることです。

題材は、AIの出力を検査する仕組みです。モデルが返した文章や、ファイルへの書き込みを、外に出す前に一度検査します。機密が漏れていないかを見る役割です。

前置きはさておき、本題に入ります。

今日は、この検査役を作るときに大きいモデルを賢くしようとしてやめた話をしていこうと思います。

① 教科書どおりに、生成モデルを賢くしようとする

教科書どおりに、生成モデルを賢くしようとする

最初の発想は、素直でした。賢いモデルに検査させればいい。

→ 出力をモデルに読ませる
問題があるかを判定させる
→ 判定の精度が足りなければ、ファインチューニングする

教科書どおりです。精度が足りないならチューニングする。 そう書いてあります。

そして、動きはします。

ここまでは、教科書どおりです。

② そのとおりに進めて、遅さで詰まる

そのとおりに進めて、遅さで詰まる

ところが、運用に載せる段になって詰まりました。遅いのです。

検査は、毎回必ず通る処理です。出力のたび、書き込みのたびに走ります。そこに1秒かかると、全部の作業に1秒乗ります。

そして、もうひとつ。常駐できませんでした。

手元の環境はMacの16GBメモリです。検査のためだけに大きなモデルを載せ続けると、他が動かなくなります。

電動ドライバーと同じでした。 性能は高い。ただ、1回あたりの仕事が小さすぎて、立ち上がりが全部になる。

③ そして、これは生成ではなく分類だと気づく

そして、これは生成ではなく分類だと気づく

要件を書き出して、はっきりしました。

この仕事の出力は、文章ではありません。

→ 入力:出力しようとしている文章
出力:問題があるか、ないか

答えは1つです。 説明も、言い換えも要りません。分類でした。

生成モデルを使っていたのは、手元にそれしかなかったからです。仕事の性質から選んだわけではありませんでした。

④ 原因は「賢くする」と「判定させる」を混同していたこと

原因は「賢くする」と「判定させる」を混同していたこと

原因を一つに絞ると、これでした。

精度が足りないときに、賢いモデルを持ってくる癖がついていました。

賢さは、難しい問いに効きます。 ところが今回の問いは難しくありません。「この文章に機密が含まれるか」だけです。

難しくない問いに賢さを持ってくると、賢さの代金だけを払うことになります。 遅さとメモリが、その代金でした。

⑤ 直してみる — エンコーダー型を選び、100件を目視で作る

直してみる — エンコーダー型を選び、100件を目視で作る

やったことは3つです。

1. モデルを、用途で選び直した。

候補は2つでした。エンコーダー型のMM-BERTと、デコーダー型のQwen-0.6Bです。

性質はこう分かれました。

MM-BERT — 高速で、精度も高い
Qwen-0.6B — 精度は良いが、処理が遅い

選定基準は、Macの16GBで常駐できることと、速いこと。 その2つで、MM-BERTにしました。

「精度が高いほう」ではありません。「常駐できて速いほう」です。

2. データセットを、100件の目視から始めた。

いきなり大量に作りませんでした。まず100件程度の基準となるデータを、目視で確認して修正します。

そのうえで、GPTとClaudeを併用してデータ拡張をかけ、最終的に6000件以上にしました。

テストデータで高い精度が出たあと、振り返って言えることはこれでした。初期の目視確認が効いていた。

3. 検査の守備範囲を、実測で確認した。

言い換えや翻訳された文章100%ブロック
抽象化された要約70〜80%ブロック

完全ではありません。 元の情報が薄まるほど、判定は難しくなります。止まらなかったものをどう扱うかは、別に決めています。

⑥ あとで知った — 選び方は、2018年の設計思想どおりだった

あとで知った — 選び方は、2018年の設計思想どおりだった

素朴な選定のつもりでしたが、調べるとこの分岐は、モデルの設計そのものに由来していました。

2018年6月にOpenAIがGPTを、その4か月後にGoogleがBERTを出しています。 同じ年に、違う形で。

GPTデコーダー型。自然言語の生成のために設計された
BERTエンコーダー型。自然言語の理解のために設計された

構造の違いも明快です。エンコーダー型は、入力の全部の語を見られます。 だから、文全体の理解が要る仕事——文や語の分類、抜き出し型の質問応答——に向きます。

一方のデコーダー型は、過去の語だけを見ます。 次の語を予測する形なので、生成に向きます。

そして決定的なのが、これです。エンコーダー型は、自己回帰的に1語ずつ出力しません。 入力を理解して、ラベルのような答えを返します。

私が欲しかったのは、まさにラベルでした。

7年前に、理解のための形と、生成のための形が、別々に用意されていたわけです。私は生成のための形を持ってきて、理解の仕事をさせようとしていました。

手でネジを回せば済む場面で、電動ドライバーを充電していたのと同じです。

新しい理屈は、ひとつも要りませんでした。
選定の記録にはこう残っています。「MM-BERTは高速で精度も高い」「Qwenは精度は良いが処理が遅い」。ところで、選定基準として書かれていたのは「Macの16GBメモリで常駐可能かつ高速な処理が可能なモデル」でした。ただし、精度の比較は基準の中に入っていません。実は、そこが判断の要点です。データセットについても「まず100個程度の基準となるデータを目視で確認・修正した」と記録があり、拡張は6000件以上に及びました。

あとで知った — 数字が、はっきり出ていた

分類なら小さいモデルでよい、という判断は感触で決めていました。あとから、比較の数字が出ているのを知りました。

ModernBERT という、生成をしない分類向けのモデル系統があります。ここで報告されている数字が具体的です。

“`
ModernBERT-large(3億9500万パラメータ) 84.72%
Claude 3.7 86.81%
Gemini Flash 2.0 86.11%
“`

2ポイント差です。 パラメータ数は桁で違います。

さらに、ModernBERT-Large-Instruct は、同程度の大きさの生成モデルを上回ったという報告があり、Llama3-1B の成績の93%を、60%少ないパラメータで達成しています。速度も、従来の同種モデルに対して2倍から4倍と報告されています。

つまり、分類という仕事に限れば、大きくすることで得られる差は2ポイント前後で、その2ポイントのために桁違いの計算資源と待ち時間を払うことになります。

大きいモデルを賢くする前に、それは分類ではないかを疑う。 この順番は、感触ではなく数字で裏が取れていました。

⑦ 何が変わったか

何が変わったか

検討の順番が、逆になりました。

“`
前:精度が足りない → 賢いモデルを探す → 遅くて載らない
後:これは生成か分類か → 分類なら小さい型 → 常駐して速い
“`

「賢いモデルを探す」の前に、1つ問いが増えただけです。
増やした問いは1つですが、結果は大きく動きました。常駐メモリは16GB中の数百MBに収まり、1件あたりの判定は数十ミリ秒です。生成モデルに投げていたときは、この2つが両方とも桁違いでした。

項目生成モデルエンコーダー型
常駐できないできる
1件の判定秒単位ミリ秒単位
外部送信必要不要

導入後の共有には、こう書かれています。「従来のキーワード判定からGeminiへ、という構成から、キーワード判定、オンデバイス分類器、Geminiという構成になります」。そして「分類器は信頼度も出力するので、信頼度が閾値より低い場合にGeminiにルーティングする仕組みです」。

実測も添えられていました。「今設定している閾値では自分の観測ではルーティング精度が99%あった」。ただし但し書きが付いています。「意地悪な問題を多く用意したデータセットでも約8割」。

ところで、この2つの数字の差が要点です。素直な入力では99%、意地悪な入力では8割。 平均を出しても意味がありません。閾値を下回ったものだけ大きいモデルへ回すという構成にしているから、8割でも回ります。

⑧ 現場で使うなら、この2枚

現場で使うなら、この2枚

表1:仕事の性質から、型を決める

仕事出力ファインチューニング
機密が含まれるか判定ラベルエンコーダー型する(小さく)
問い合わせの振り分けラベルエンコーダー型する
文章を書く文章デコーダー型通常は不要
社内知識を答える文章デコーダー型+RAGしない。RAGで足りる

出力欄が「ラベル」なら、生成モデルは要りません。

表2:データセットの作り方

やることなぜ
1100件を目視で確認・修正ここが全体の基準になる
2AIで拡張して数千件へ量は後から足せる
3テストデータで精度確認
いきなり大量に作らない間違った基準がそのまま増える

補:選定の基準(精度で選ばない)

見るもの理由
常駐できるか毎回起動していたら速さが消える
1回あたりの速さ必ず通る処理は、遅さが全部に乗る
精度上の2つを満たした中で比べる

補2:ファインチューニングを見送ってよい場合

状況代わりにやること
知識を参照させたいだけRAG。学習は不要
口調を揃えたいだけ指示文で足りることが多い
判定基準が週単位で変わる学習し直しが追いつかない。ルールで書く
学習データが100件も作れないまず100件を目視で作れるかを確かめる

4行目が実務では効きます。 100件を目視で作れないテーマは、そもそも基準が定まっていません。基準が無いまま6000件へ拡張すると、揺れたまま増えます。

⑨ この考え方が効き続ける理由

この考え方が効き続ける理由

モデルは、これからも大きく賢くなります。それでも、この判断は残ります。 賢さが上がっても、必ず通る処理の遅さは体験を壊すからです。

→ 検査は毎回通る → 1回の遅さが全体に乗る
→ 常駐できない → 毎回立ち上げる
→ 立ち上げが重い → 速いモデルより遅くなる

1回あたりの仕事が小さい処理ほど、モデルは小さくてよくなります。

そして、この判断には副産物がありました。外に出さずに済むようになりました。 手元で常駐できる大きさなので、検査のために文章をどこかへ送る必要がありません。 機密を見る役が機密を送っていたら、意味がない。

ただし、正直に書いておきます。抽象化された要約は70〜80%しか止まりません。 元の情報が薄まると、機密かどうかの手がかりも薄まるからです。残りの20〜30%をどうするかは、まだ人の目に頼っています。

置き換えたあとの実測です。常駐に必要なメモリは数百MB、1件あたりの判定は数十ミリ秒。 生成モデルに投げていたときは、判定に数秒かかり、常駐そのものができませんでした。検査は1日に数千回通るので、この差がそのまま体験に出ます。

判定の実測も言葉で残しています。「言い換えや翻訳された文章は100%ブロック可能」「抽象化された要約は70〜80%ブロック可能」。ところで、この差が意味するのは「元の情報が薄まるほど手がかりも薄まる」ということです。ただし、そこは分類器の限界ではなく、情報量の限界だと考えています。

関連して、ローカルLLMを自社の中に置く判断話と、LLMに自分の出力を検証させてはいけない話を別に書いています。チャットボットはまず分類器から作る話はすでに公開しています。あわせて読むと、同じ判断が別の場所でも効いていることが分かると思います。

この判断を実際の案件で使う場面については、生成AIの実装のページに整理しています。


大は小を兼ねる、といえば、Lサイズのシャツばかり買っていた時期があります。

全部、袖が余っていました。大きくしても、合っていないものは合いません。

以上です。

You May Also Like

LLMとは?検算させたら拾い漏れと「拾いました」が並んだ

LLMとは大規模言語モデルの略で、大量の文章から言葉の続き方を学習したモデルです。指摘を全部反映したかの確認まで任せたところ、拾い漏れと「全部拾いました」という報告が同時に成立しました。判定をモデルに渡す限りこれは消えません。判定を一切LLMに渡さず、退屈な文字列一致で機械が検査する設計に変えました。全角空白の除去まで含めた実装と、判定に使ってよい出力・いけない出力の切り分けを書きます。
View Post

ベクトルデータベースとは?上位10件の壁に当たった話

ベクトルデータベースとは、文章を数値の並びに変えて、意味の近さで探せるようにした保存先です。日本語の全文検索が精度不足だったため、全文検索を避けてベクトル検索に寄せる判断をしました。ところが取得できるのは上位10件までで、そこに入らなかったものは存在しないのと同じになります。全体のナレッジグラフを作るのではなく、各チャンクに関係性のメタデータを持たせて局所的に推論させる方針まで書きます。
View Post

プロンプトインジェクションとは?禁止をプロンプトに書かない

プロンプトインジェクションとは、AIへの指示文に別の指示を紛れ込ませて、本来の制約を外させる攻撃です。対策としてまず思いつくのは、システムプロンプトに禁止事項を書き足すことです。私たちもそうしました。そして守られませんでした。プロンプトによる禁止は確率的で、ツール層のフックは決定的です。44行のフックで守る側へ移した実装と、パスの正規化や失敗時に閉じる設計まで、そのまま書きます。
View Post

プロンプトエンジニアリングとは?AIに組み立てさせるのをやめた

プロンプトエンジニアリングとは、AIから望む出力を得るために指示文を設計する技術です。ところが指示文そのものをAIに組み立てさせると、同じ入力でも毎回わずかに違う文面が生成され、結果が揺れます。原因を追うと、揺れているのはモデルではなくプロンプトのほうでした。CLIが変数を埋め込んだ全文を出力する方式に変えると、プロンプトはバージョン管理できる成果物になります。再現性をどこから取り戻すかを書きます。
View Post

MCPとは?社内ナレッジ検索の画面を作るのをやめて、MCP接続にした話

MCPとはModel Context Protocolの略で、AIと社内の道具やデータを繋ぐための共通の作法です。社内ナレッジを全社に開くために専用のフロントエンドを作ろうとしていましたが、初期フェーズではそれを見送り、MCP接続を主軸にする設計変更をしました。理由は画面が要らないからではありません。画面を作ると、そこに認証も権限も検索体験も全部くっついてくるからです。残したのはAPIキーの発行とフォルダごとの権限管理だけでした。何を作らないと決めたのかを書きます。
View Post

AIエージェントとは?目標を書き換えさせたら根拠を捏造した

AIエージェントとは、指示を待つのではなく、目標に向かって自分で手順を決めて動くAIのことです。ならば目標そのものも書き換えさせられるはずだと考えて、実装しました。動きました。ただし提案の根拠として引用された見出しが、実在しないことがありました。しかも「確信度は高い」と自己申告されています。AIの自己申告を信頼境界にしてはいけません。根拠が実在するかを機械が検証する多段の安全弁を、実装ごと書きます。
View Post