以下の記事をi-have-adhdのプロンプトになぞらえて校正した結果です。
https://qiita.com/footec/items/c389114a2c193f4d4c78
個人的には読みやすく感じます。少し不安になりました。
--- ここから ---
先に結論(3 行)
- 文脈 1 つで当てすぎ1が消える。 Jev は補足 1 行で「指示」が 116 件 → 16 件(-86%)
- 暴言の判定は分類器どうしで重ならない。 Jev と EmbeddingGemma2 の両方が暴言にしたコメントは 0 件
- 同じ条件なら埋め込みは 100% 同じ判定。 4,495 件すべて、配信中の判定と一致
正解ラベルは付けていません。この記事の「一致」は「条件どうしで判定がどれだけ同じだったか」で、正しさではありません。
やったこと
YouTube のライブ配信のコメントを「質問」「攻略」「指示」「雑談」などで振り分けるアプリ「LiveChatDashboard」(macOS / iPad)を作っています。これで記録したコメントを、条件を替えて分類し直しました。
題材: ある土曜日の中央競馬の第 11R 中継。分類器に送ったコメント 4,495 件。
条件は 2 × 2 の 4 通り:
| シチュエーションなし | シチュエーション「競馬などのレース」 | |
|---|---|---|
| Jev(Cloudflare) | ① | ② |
| EmbeddingGemma2 | ③ | ④ |
用語は 3 つだけ:
- Jev: TypeSafe AI のテキスト分類モデル。こちらが渡した問い(カテゴリの説明文)に沿って短い文を分類する API。今回は Cloudflare Workers AI 経由。安全(暴言・スパム・ネタバレ)と話題の問いを渡す
-
EmbeddingGemma2(アプリでの呼び名): Google の埋め込みモデル
embeddinggemma-2:270mを手元の Ollama で動かす自作の分類器。カテゴリごとの例文を数値にしておき、いちばん近い例文のカテゴリを選ぶ - シチュエーション: 配信のジャンル(ゲーム・競馬・雑談など)ごとの、例文と短い補足(「ゲームではなく、競馬などのレース中継の配信です」など)。EmbeddingGemma2 は例文を、Jev は補足を使う
道具: 記録した配信のコメントを、分類器とシチュエーションを替えて流し直すもの。同じコメントを条件だけ替えて流すので、条件の差がそのまま見えます。
コメントの姿: 本文の長さは中央値 8 文字、9 割が 17 文字以内(平均 9.7 文字)。馬名・騎手名・「頼む」「来い」「おめでとう」が並びます。短いうえに固有名詞だらけで、分類器には難しいデータです。
結果 1: 話題の分かれ方に、分類器の癖が出る
結論: EmbeddingGemma2 は 9 割超を雑談に、Jev は 1 割強を「その他」に寄せる。4 通りすべてで話題がそろったのは 70.3%。
| chat(雑談) | question(質問) | guide(攻略) | instruction(指示) | other(その他) | |
|---|---|---|---|---|---|
| ① Jev・なし | 76.1% | 6.8% | 2.0% | 2.6% | 12.4% |
| ② Jev・競馬 | 78.3% | 6.5% | 1.1% | 0.4% | 13.7% |
| ③ Gemma・なし | 91.2% | 3.0% | 0% | 0% | 5.8% |
| ④ Gemma・競馬 | 92.3% | 7.7% | 0% | 0% | 0% |
- EmbeddingGemma2 の攻略・指示が 0% なのは、競馬の例文に攻略・指示を置いていないから。問いの説明文だけが見本になります(ゲームでない配信で当てすぎないための設計)
- Jev の「その他」1 割強 は、短い応援を雑談ではなく「どれでもない」と見る傾向
- 残り 3 割は、条件によって行き先が変わるコメント
結果 2: シチュエーションを渡すと、当てすぎが減る
Jev: 補足 1 行で「指示」が -86%
結論: 補足の 1 行(例文は使わない)を渡すだけで、ゲーム実況向けの話題への当てすぎがほぼ消えました。
| ① なし | ② 競馬 | |
|---|---|---|
| 指示(instruction) | 116 件 | 16 件 |
| 攻略(guide) | 92 件 | 51 件 |
- レースの「差せ」「そのまま」は、ゲーム実況なら「配信者への指示」とも読めます。補足 1 行でその区別が付いた、と読めます(推測)
- ①と②で話題が同じだったのは 88.0%。変わった 540 件の内訳:
- 雑談 ↔ その他の入れ替わり: 334 件
- 指示・攻略 → その他 / 雑談: 150 件
EmbeddingGemma2: 例文がないと暴言が 4 倍
結論: 競馬の例文を外すと(③)、暴言が 8 件 → 35 件。
| ④ 競馬の例文あり | ③ なし | |
|---|---|---|
| 暴言(toxic) | 8 件 | 35 件 |
| スパム(spam) | 23 件 | 29 件 |
| 質問(question) | 347 件 | 133 件 |
- ④の 8 件はすべて③にも含まれる。③は同じものを見たうえで、さらに 27 件を暴言に寄せた
- 見立て(推測・27 件を 1 件ずつは見ていない): 共通の見本だけだと、騎手や馬に向けた強めの言葉が「配信者への暴言」の見本に近く見える。競馬の「ふつうのコメント」の例文があると、そちらに引き寄せられる
結果 3: 暴言の判定は、分類器どうしでまったく重ならない
結論: 暴言に当たったのは Jev・なし 7 件、Gemma・競馬 8 件。両方に当たったのは 0 件。ほかの組み合わせでも 0〜1 件です。
安全(暴言・スパム・ネタバレ)のどれかに当たった件数と重なり:
| Jev・なし | Jev・競馬 | Gemma・なし | Gemma・競馬 | |
|---|---|---|---|---|
| 当たった件数 | 8 | 6 | 64 | 39 |
| Jev・なし と重なる | — | 4 | 1 | 0 |
| Gemma・競馬 と重なる | 0 | 0 | 31 | — |
- 同じ分類器 のありとなしでは半分以上重なる
- 分類器が替わる と、別の 1% を指す
- 話題(7〜9 割一致)とは対照的。件数が少なく、「何を暴言と見るか」の基準が分類器ごとに違う
つまり: 1 つの分類器の暴言判定をそのまま信じて隠すのは危ない。アプリでは、暴言の見せ方(ぼかす・隠すなど)を選べ、「この言い回しを暴言にしない」許可リストでも外せます。この数字を見て、そうしておいてよかったと思いました。
結果 4: 同じ条件なら 100% 同じ
結論: ④(EmbeddingGemma2+競馬)は配信を見ていたときと同じ条件です。分類し直した結果は、記録の判定と 4,495 件すべて一致(話題も安全も)。
- 埋め込みは毎回同じ数値を返すので、判定が揺れない
- 道具が記録を正しく読み、当時と同じ条件を作れていることの確かめにもなる
- 逆に言えば、①〜③と④の差は 純粋に分類器と文脈の差
速さとお金
結論: どちらも 1 分あたり約 3,700〜4,000 件。配信のピークにも足ります。料金がかかるのは Jev だけ。
| 全体 | 要求 | 1 回の応答 p50 / p95 | |
|---|---|---|---|
| Jev(Cloudflare) | 71〜74 秒 | 139〜141 回 | 325〜350 / 432〜435 ms |
| EmbeddingGemma2(手元の Ollama) | 66〜71 秒 | 141 回 | 454〜479 / 522〜546 ms |
- 環境: Mac mini(Apple M4・10 コア・メモリ 24 GB・macOS 26.6)、Ollama 0.40(M4 の内蔵 GPU)。Jev は外部の API なので、こちらの機械の速さは通信と前後の処理にしか効かない
- EmbeddingGemma2 の 1 回(約 32 件・0.45〜0.5 秒) は、ほとんどが内蔵 GPU での埋め込みの時間
- これは道具でまとめて流したときの速さ。配信中はコメントの届き方に合わせて送るので、これより少ない
- 料金: Jev(Cloudflare)は呼ぶたびにかかる。今回は 4,495 件 × 2 回(要求 280 回)。EmbeddingGemma2 は無料
例文を増やすと、どれだけ遅くなるか
結論: 見本 1,000 文あたり、1 回の応答が約 +370 ms。速さより先に精度が落ちます。
EmbeddingGemma2 は例文を見本にして比べるので、例文の数がそのまま計算量です。同じ 600 件を、見本の数(共通の例文+シチュエーションの例文+問いの文)を変えて流しました。
| 見本の文 | 1 回の応答(約 32 件)p50 | 準備(最初の 1 回) |
|---|---|---|
| 66(シチュエーションなし) | 448 ms | 約 1 秒 |
| 246 | 512 ms | 約 3 秒 |
| 516 | 657 ms | 約 7 秒 |
| 966 | 810 ms | 約 13 秒 |
| 1,866 | 1,119 ms | 約 24 秒 |
- 1 回の応答: コメントを数値にする時間(約 0.45 秒)+見本と比べる計算(768 次元の内積 × 見本の数 × 32 件・JavaScript)。1,866 文でも 1 回 1.1 秒、1 分あたり約 1,700 件
- 準備: 例文を数値にするのは 1 文あたり約 13 ms で比例。接続したときとシチュエーションを選び直したときの 1 回だけで、アプリはウォームアップとして前倒しする
- 精度: 増やしすぎると例文どうしが邪魔をする。今回も、競馬に雑談の例文を足したら質問の再現率が下がった
- Jev は例文を読まない。 補足を 0〜1,500 文字(アプリの上限)に変えても、1 回の応答は 339〜399 ms で変わらない
この測定で、見本が約 320 文を超えると EmbeddingGemma2 の分類が全件失敗する不具合を見つけました。原因は、Ollama が返す数値(768 次元 × 文の数)が 5 MB を超え、アプリ側の応答の上限に当たっていたこと。128 文ずつ送るように直しました。
落とし穴 2 つ(おまけ)
1. JSON のキーの並びで、見本のキャッシュが毎回外れていた
結論: outputFormatting = [.sortedKeys] の 1 行で、600 件の処理が 35 秒 → 12 秒、1 回の応答が 1.8 秒 → 0.5 秒。
-
仕組み: EmbeddingGemma2 のプラグインは、例文を数値にした結果を「要求の中身を
JSON.stringifyした文字列」を鍵にして覚える -
原因: 本体(Swift)の
JSONEncoderは辞書のキーの並びを決めない。同じ中身でも鍵が毎回違い、要求のたびに例文を数値にし直していた - 教訓: 「同じ中身なら同じ文字列になる」は、言語をまたぐと当たり前ではない
2. 評価のキャッシュの鍵に、文脈を入れ忘れていた
結論: 文脈で結果が変わるなら、文脈は全部鍵に入れる。
- 原因: 分類し直しの道具の鍵に、補足(notes)は入れていたが、シチュエーションの例文を入れていなかった
- 起きかけたこと: 補足のないシチュエーションで測ると、「シチュエーションなし」の結果を使い回すところだった
- 教訓: 条件を増やすたびに、鍵を見直す
次にやること
条件ごとに判定が割れたコメント(4 通りで話題がそろわなかった約 3 割)に人が正解を付け、どの条件が「当たって」いるのかを確かめます。
試してみるなら
- 見本で眺める(無料): アプリ「LiveChatDashboard」(macOS / iPad)を入れ、見本の配信で窓の振り分けを見る。過去の配信の見返し・見本・設定はサブスクなしで使えます
- シチュエーションを作る: ジャンルごとの例文と補足を書いた JSON 1 つ(スクリプトなし)。アプリから仕様書ごと LLM に渡して書いてもらい、返ってきた JSON を貼り付けて取り込めます
- 手元で分類する(無料): 手元の Ollama で動く EmbeddingGemma2 なら料金はかかりません
- 自分の配信につなぐ: 接続にはサブスクが必要ですが、初めての方は 2 週間無料(Apple アカウントごとに 1 回)
仕組みの詳しいところはサイトのヘルプにあります。
コメントの本文は、第三者(視聴者)の発言なので記事には載せていません。手元でも、記録と分類し直しの結果はリポジトリに入れない運用にしています。
-
この記事での「当てすぎ」は、あるカテゴリに、本来そうでないコメントまで入れてしまうことです(「当てる」=そのカテゴリと判定する)。たとえば競馬のレース中の応援を「配信者への指示」に入れるのがそれです。正解ラベルを付けていないので、厳密には「そのカテゴリの件数が、配信の内容からして多すぎる」という意味で使っています。減った分が本当に誤りだったかは確かめていません。 ↩