Mac で動く Laya は Jev の代わりになるか
判断をクラウドのAPIに投げると、通信の往復が乗るし、入力が外に出る。同じことが手元で済むなら済ませたい。
Jev の公開後、文章を生成せず判断だけを返すモデルが、重みを公開する形でいくつか出ている。学習済みの重みが誰でも落とせて、ライセンスの範囲で自由に使える形を、オープンウェイトと呼ぶ。クラウドのAPIを経由しないので、通信も課金もない。
その一つが Laya である。
生成しないモデルの作り
Laya は双方向エンコーダに判断ヘッドを載せた構成を取る。
用語を開くと、こうなる。文章を扱うモデルには、前から順に読んで次を予測するものと、文章全体を一度に見て各単語の意味を捉えるものがある。後者が双方向エンコーダで、BERT 系のモデルがこれにあたる。続きを書く用途には向かないが、すでにある文章を分類したり、意味を測ったりするのは得意である。
判断ヘッドというのは、そのエンコーダの出力を受けて答えを出す小さな層のことだ。「この文章は違反か」のような問いに、確率を一つ返す。
この構成だと、文章を一度通すだけで答えが出る。入力を頭から最後まで一回計算することをフォワードパスと呼ぶが、1回のフォワードパスで終わるので速い。LLM がトークンを一つずつ並べるのとは、そもそもやっていることが違う。
Apache-2.0 で重みが公開されていて、Apple Silicon 向けに移植された laya-mlx がある。MLX は Apple が出している機械学習フレームワークで、Mac のGPUとメモリの作りに合わせてある。
学習済みの重みは、用途別に何種類か公開されている。この単位をチェックポイントと呼ぶ。Laya には3つあって、括弧内はパラメータ数、つまりモデルの大きさである。
- 英語版:ModernBERT-large(421M)
- 多言語版:mmBERT-base(322M)
- 型付き判断に特化したもの:ModernBERT-large(421M)
多言語版だけ小さい。日本語を扱うならこれを選ぶことになる。
50%という数字の読み方
金融機関名の同一性判定が 50% だった。
同じ会社かどうかを二択で答える質問で 50% なのだから、当てずっぽうと同じということになる。最初はそう読んだ。
実際には違った。laya は10件すべてに「同じ会社」と答えていた。
| 名称A | 名称B | 正解 | laya |
|---|---|---|---|
| 三菱UFJ銀行 | 株式会社三菱UFJ銀行 | 同一 | 1.00 |
| みずほ銀行 | みずほ信託銀行 | 別 | 0.99 |
| 三井住友銀行 | 三井住友信託銀行 | 別 | 1.00 |
| 楽天銀行 | 楽天証券 | 別 | 1.00 |
| ゆうちょ銀行 | りそな銀行 | 別 | 1.00 |
ゆうちょ銀行とりそな銀行を 1.00 で同じ会社と答える。正解が同一5件と別5件なので、全部に「同一」と答えると、ちょうど 50% になる。
数字は間違っていないが、意味が違う。「半分当たる」のではなく「見分けていない」。一致率だけを表に並べていたら、たぶん気づかないまま「二択なら五分五分か」と書いていた。
以降は、10件すべてに同じ答えを返した組み合わせに印を付けて数える。そこの一致率は、モデルの性能ではなくケースの偏りを写しているだけなので、読まない。
質問文を日本語から英語にする
同じことが frustration(3段階のスコア)でも起きていた。10件すべてが「苛立ちあり」だった。
ここで、崩れているのが日本語の本文なのか日本語の質問文なのかが分からなくなった。Jev と同じく、Laya にも判断の材料になる文章と、聞きたいことの定義を渡す。前者は日本語のまま、後者だけ英語に書き換えて回し直す。
| 質問 | 質問文 ja | 質問文 en |
|---|---|---|
| コンプラ表現検出 | 40% | 80% |
| department | 40% | 70% |
| needs_same_day | 70% | 80% |
| 金融機関名の同一性 | 張り付き | 張り付き |
| frustration | 張り付き | 張り付き |
コンプラ表現検出が倍になった。判断の材料は日本語の文面のままである。
日本語が読めていなかったのではなく、日本語で聞かれると崩れていた。本文と質問文で、効き方が別になっている。
チェックポイントを型付き判断特化のものに替えると、日本語の質問文でもコンプラ表現検出は 80% に上がった。ただし needs_same_day が全件「当日対応が必要」に張り付く。英語版のチェックポイントは、日本語の本文に対しては軒並み崩れた。
どのチェックポイントでも、どちらの言語でも動かなかったものが2つある。金融機関名の同一性は6通り中5通りで全件「同一」、frustration は6通りすべてで全件「苛立ちあり」だった。
Jevは質問文の言語で動かない
比較のため、Jevにも英語の質問文で同じ30件を投げた。
| Jev ja | Jev en | laya 多言語 ja | laya 多言語 en | |
|---|---|---|---|---|
| コンプラ表現検出 | 90% | 90% | 40% | 80% |
| 金融機関名の同一性 | 90% | 90% | 張り付き | 張り付き |
| department | 100% | 100% | 40% | 70% |
| needs_same_day | 100% | 100% | 70% | 80% |
| is_offensive | 100% | 100% | 80% | 張り付き |
| frustration | 80% | 90% | 張り付き | 張り付き |
Jevはほとんど動かない。frustration の1件差も、確信度 0.33 の境界ケースが反転しただけだ。
laya のほうは質問文の言語で倍近く動く。322M のモデルと、クラウドで動く規模のモデルとの差は、精度より先に、聞き方で崩れるかどうかに出た。
速さは本当
推論は30回の平均で 60.4ms だった。通信がないので、これがそのまま応答になる。最大は 607ms で、これは最初の1回だった。
Jevを同じ30件で測ると中央値 261ms、たまに1秒を超える。ネットワークの往復ぶんだけ明確に速い。
課金もない。モデルの読み込みは1秒弱で、型付き判断特化のチェックポイントを初めて落としたときで19秒だった。
どこまでなら任せられるか
needs_same_day の 80% と department の 70%(どちらも多言語版、英語の質問文)は、一次の振り分けの下書きとしてなら使える水準に見える。人が最後に見る前提で、問い合わせの並び替えと担当の初期値を作るくらいの使い方だ。無料で、通信もなく、60ms で返る。
金融機関名の同一性と3段階のスコアは、この構成では無理だった。見分けていないので、どこで切るかを決める以前の問題になる。
質問文を英語で書く、というのは運用として現実的ではある。判断の材料は日本語のままでいいので、書き換えるのは質問の定義だけで済む。ただ、それで上がるのがどのタスクなのかは、回してみるまで分からなかった。
ケースは各10件しかない。1件の当たり外れで10ポイント動くので、ここに出した数字は傾向までしか言えない。それでも、全件に同じ答えを返しているかどうかだけは、10件でもはっきり見える。