追記(2026/09/26) 公開後に 3 点を訂正した。(1) Jev の公開時期を「2026 年 5 月」と書いていたが、早期アクセスの開始は 2026 年 9 月 15 日。(2) sokudan の設計を cross-attention と説明していたが、この設計は A/B テストで撤回済みで、v0.1 は joint encoding。経緯と数字を「cross-attention をやめた理由」の節に書いた。(3) 「一日でやったらどうなったか」は初日(v0.0)の結果で、その後 v0.1 を公開した。v0.1 の結果を追加した。訂正履歴は末尾。
概要
- TypeSafe 社の Jev(「System One モデル」)の OSS 再現が乱立している。テキストを生成せず、型付きの判断と較正済み確率を 1 回のフォワードパスで返すやつ
- 最も本格的な再現 Laya(ModernBERT-large 421M)を、日本語 300 件で実測した
- 多クラス選択(choice)は普通に使える。多数決の 2 倍、ランダムの 3 倍
- 順序尺度(score)は壊れている。原因は「提示された選択肢の先頭を 300 件中 0〜1 件しか選ばない」位置バイアス。5 条件で再現した
- 真偽判定(bool)は多数決以下。常に「いいえ」と答える方が 16pt 高い
- 温度較正で ECE は直るが、精度は 1pt も動かない
- なので日本語版を作った。初日は score で Laya に勝ち、bool は転移しなかった。v0.1 では 3 型すべてで laya-multilingual を上回った
リポジトリ: https://github.com/hiroki-abe-58/sokudan
学習済みモデル: https://huggingface.co/GeneLab/sokudan-ja-310m
System One モデルとは何か
2026 年 9 月 15 日に TypeSafe AI が早期アクセスとして出した Jev は、公式ドキュメントで「System One モデル」と呼ばれている。
公式ドキュメントの言い方を借りると、LLM は人間が読むテキストを作るために設計されており、コードが消費する判断が欲しいときにテキスト生成システムに構造化された判断を無理やり出させてパースし直すのはミスマッチだ、という問題意識から来ている(TypeSafe 公式ドキュメント Introduction より要約)。
やることは 3 種類しかない:
| 質問タイプ | 何を聞くか | 返るもの |
|---|---|---|
| choice | 選択肢から 1 つ選ぶ | 選択、各選択肢の確率、confidence |
| score | ルーブリック上で採点 | スコア、分布、confidence |
| bool(Jev では noul) | この文は真か | P(true) |
state(判断対象のテキスト)と複数の質問を 1 リクエストで投げると、全質問が同じ state に対して独立に評価されて返ってくる。テキスト生成なし、パースなし。
OSS 再現が乱立している
Jev 公開から 1 週間ほどで、再現を名乗るものが多数出ている。大別すると 2 種類:
- ワイヤ互換のブリッジ(例: GitHub Next の LocalJev)。API の形だけ合わせて、中身は拡散 LLM に JSON で確率を自己申告させている。README 自身が「ワイヤ互換だが数学的に等価ではない」と断っている
-
本物の再現(例: convaiinnovations の Laya)。エンコーダ + 選択肢ごとの
[MASK]トークンでスコアリング、単一フォワードパス。RLCD という較正向けの強化学習で学習
今回測ったのは後者の Laya。421M パラメータ、Tesla T4 で動く。RTX 5090 だと 1 件 22ms。
Laya のモデルカードは自分の弱点を隠していない。多言語版は 51 言語のマクロ平均精度 0.227 で、クメール語に至っては信頼度 0.952 で精度 0.000 と書いてある。自信満々に全部外すという一番タチの悪い壊れ方。
じゃあ日本語はどうなのか。誰も測っていなかった(私の知る限り)。
測り方
評価セット bench_ja(300 件)
ローカル LLM(Qwen3 30B-A3B)にラベルを先に指定して業務メールを書かせた。「請求部門宛の、やや苛立った、解約をほのめかす問い合わせを書け」のように。生成条件がそのまま正解ラベルになるので、アノテーションが要らない。
各文書に 3 問:
- choice: どの部署が担当すべきか(4 択)
- score: 緊急度は(急がない / 早めに / 業務が止まっている)
- bool: 解約を示唆しているか
比較対象
全部同じ 300 件、同じ質問、同じスコアリングコードで測った。
convaiinnovations/laya-multilingual-
convaiinnovations/laya(英語版に日本語をそのまま入れた場合) - 多数決クラス
- ランダム
- LLM-as-classifier(Qwen3 30B-A3B、temperature 0、選択肢を列挙して 1 単語で回答)
注記: bench_ja の生成者と LLM-as-classifier が同じモデルなので、LLM の行は「上限の目安」であって公平な比較対象ではない。書いた本人が分類しているのだから。
Jev 本体は測っていない。TypeSafe の利用規約(Master Customer Agreement 2.3(b))が、同サービスおよびその出力を類似製品の開発に用いることを禁じているため。
結果
| 対象 | choice acc | choice ECE | score RPS ↓ | score acc | bool acc |
|---|---|---|---|---|---|
| laya-multilingual | 0.747 | 0.148 | 0.232 | 0.443 | 0.543 |
| laya(英語版) | 0.467 | 0.108 | 0.200 | 0.460 | 0.303 |
| 多数決 | 0.380 | — | 0.197 | 0.460 | 0.703 |
| ランダム | 0.253 | — | 0.201 | 0.403 | 0.513 |
| LLM-as-classifier(参考) | 0.893 | 0.104 | 0.167 | 0.703 | 0.870 |
| laya-multilingual + 温度較正 | 0.747 | 0.087 | 0.196 | 0.443 | 0.543 |
RPS は ranked probability score。順序尺度用の指標で、「隣に外す」より「両端に外す」を重く罰する。低いほど良い。
独立に 2 回実行して全数値が小数第 3 位まで一致している。
choice: 使える
0.747。多数決の 2.0 倍、ランダムの 3.0 倍。部署ルーティングのような素直な多クラス選択なら、laya-multilingual は今日そのまま使える。ECE 0.148 は高めだが、温度較正で 0.087 まで下がる。
score: 壊れている、しかも理由が分かった
RPS 0.232 は多数決(0.197)より悪い。混同行列を見ると理由が一目で分かる:
| gold \ 予測 | 急がない | 早めに | 業務が止まっている |
|---|---|---|---|
| 急がない(77 件) | 0 | 58 | 19 |
| 早めに(138 件) | 0 | 78 | 60 |
| 業務が止まっている(85 件) | 0 | 30 | 55 |
最下位ラベルを 300 件中 0 回しか選んでいない。
最初は「否定形(急がない)に弱いのか」「順序尺度の学習が壊れているのか」と思ったが、追加実験で違うと分かった。
| 条件 | 提示した選択肢(この順) | 第 1 選択肢が選ばれた件数 | argmax の分布 |
|---|---|---|---|
| A 原文 | 急がない / 早めに / 業務が止まっている | 0 / 300 | [0, 167, 133] |
| B 逆順 | 業務が止まっている / 早めに / 急がない | 0 / 300 | [0, 50, 250] |
| C 言い換え | 低 / 中 / 高 | 1 / 300 | [1, 291, 8] |
| D 言い換えの逆順 | 高 / 中 / 低 | 1 / 300 | [1, 0, 299] |
| E 4 段階 | 全く急がない / 急がない / 早めに / 業務が止まっている | 0 / 300 | [0, 78, 37, 185] |
選択肢の順序を逆転しても、「低 / 中 / 高」に言い換えても、4 段階にしても、提示された順序で先頭にある選択肢を 5 条件すべてで 0〜1 件しか選ばない。
決定的なのは B と D の比較。B では最後の選択肢が「急がない」、D では最後が「高」で、意味は正反対。なのにどちらも最後に票が集中している(250 件と 299 件)。ラベルの意味ではなく位置で答えている。
順序尺度の質問では最下位ラベルを先頭に書くのが自然なので、緊急度・満足度・深刻度のような質問は実務上ほぼ全部この穴を踏む。
追記(2026/09/26): 上流への報告 この位置バイアスは Laya の Issue #131 として報告した。他の貢献者が生ロジットと「全選択肢を同一にした対照」で重み側の原因だと特定し、メンテナは描画側の変更を採らず、v0.3.7 の README の Limits 節に反映している。同じ検査を回帰テストとして research/eval/presentation_checks.py に入れる PR #259 は 2026 年 9 月 23 日にマージされた。
bool: 多数決以下
正解率 0.543。この評価セットの正例率は 29.7% なので、常に「いいえ」と答えるだけで 0.703 出る。Laya はそれを 16pt 下回った。平均 P(true) が 0.434 で、gold の 0.297 に対して系統的に true 側へ倒れている。
AUROC は 0.523。0.5 が当てずっぽうなので、閾値の問題ではなく順位付け自体ができていない。念のため閾値を gold の正例率に合わせて切り直しても精度 0.613 で、やはり多数決(0.703)に届かない。
温度較正で直るか
直らない。(質問タイプ, 選択肢数) ごとに温度を 1 つフィットすると ECE は 0.148 → 0.087(bool は 0.352 → 0.012)と大きく改善するが、精度は 1pt も動かない。温度スケーリングは確率の鋭さを変えるだけで順位を変えないので、位置バイアスには無力。
なので作った
日本語ネイティブの System One モデル「即断(sokudan)」。
- バックボーン:
sbintuitions/modernbert-ja-310m(MIT) - 入力は Laya と同じ joint encoding。質問・選択肢・state を 1 つの系列に並べ、選択肢ごとに
<mask>を置いてスコアリングする。質問ごとに state を再エンコードするので、質問数に比例して計算量は増える(バッチ化で吸収している) - score は多クラス softmax ではなく、選択肢数が動的でも CDF の単調性が構造的に保証される cumulative link で出す
- 学習データはすべてゴールドラベル付き。Laya の出力も Jev の出力も一切使っていない
cross-attention をやめた理由(訂正)
この記事の初版では、sokudan の設計を「state を 1 回だけエンコードし、質問側は別系列として cross-attention で state を参照する」と書いていた。Jev の公式ドキュメントが書いている「全質問は同じ state に対して独立に評価され、質問を増やしても応答時間はほぼ変わらない」という性質に、構造的に寄せる狙いだった。
出発点は ModernBERT の制約。3 層に 1 層しか global attention がなく(local_attention: 128、global_attn_every_n_layers: 3)、全質問を 1 系列に詰めると、遠くに置いた質問ブロックは local 層から state を見られない。質問が系列のどこに落ちるかで挙動が変わり、順序不変性も成立しない。これを避けるために cross-attention を選んだ。
ところが joint encoding と A/B で比べたら、完敗だった。held-out の bool AUROC は cross-attention の 0.506 に対して joint encoding が 0.872、非明示の意図を問う段では 0.486 に対して 0.786。事前学習で獲得した self-attention で質問と state を直接絡ませるほうが、後付けの cross-attention より未知の質問への転移がはるかに強い、という結果。そのため v0.1 は joint encoding で、「state を 1 回だけエンコードする」性質は持っていない。初版の記述は撤回する。
一日でやったらどうなったか(v0.0、負の結果を含む)
正直に書く。初日の学習データは 2,965 文書 / 18,769 ラベル付き (文書, 質問) ペア / スキーマ拡張後 40,635 例、単一シード。bench_ja のスキーマは学習に一切含めていない(未知スキーマ評価)。
| sokudan(v0.0、初日) | 多数決 | laya-multilingual | |
|---|---|---|---|
| score RPS ↓ | 0.168 | 0.197 | 0.232 |
| bool acc | 0.623 | 0.703 | 0.543 |
| bool AUROC | 0.513 | — | 0.523 |
| choice acc | 0.450 | 0.380 | 0.747 |
score は全ベースラインを上回った。 位置バイアスなしで順序尺度を扱えている。
bool は多数決を下回ったので、この時点ではモデルを公開しなかった。 既知スキーマでは AUROC 0.888 と機能するのに、未知スキーマの「解約を示唆しているか」では当てずっぽうに落ちる。学習データの bool 質問が「この文書はカテゴリ X に該当するか」のような機械的なものばかりで、意図の推論を教えていなかった。診断で「state を空にすると bool の精度が上がる」という結果まで出た。文面を読まない方がマシなモデルを公開する意味はない。
学習データ(合成文書)と bench_ja の文書長の分布。中央値は 106 トークンと 108 トークンで、分布の形もほぼ重なる。長さのズレは原因ではない。
v0.1 でどうなったか(追記)
bool 専用に、意図や態度を問う質問をデータ生成の段階から設計し直し、上で書いた joint encoding への切り替えと合わせて v0.1 を公開した。bench_ja の結果は 3 シードの平均。
| sokudan v0.1(3 シード平均) | laya-multilingual | |
|---|---|---|
| choice acc | 0.847 | 0.747 |
| score RPS ↓ | 0.090 | 0.232 |
| score acc | 0.763 | 0.443 |
| bool acc | 0.788 | 0.543 |
| bool AUROC | 0.789 | 0.523 |
3 型すべてで laya-multilingual を上回った。初日に 0.513 だった bool AUROC は 0.789 まで上がっている。
弱点も残っている。長い state で劣化すること、「質問文で終わるか」のような位置依存の表層属性への転移が弱いこと、bench_ja で P(true) を過少に予測すること。詳細はモデルカードと docs/benchmarks.md にある。その後の実験(シード間の揺れの実測と、それを削る話)は別記事にする。
公開したもの
- モデルのコード一式(Apache-2.0)
- 学習済みモデル v0.1(seed 0 が main、seed 1 / 2 は revision)
- bench_ja(300 件)と bench_en(290 件)。どちらも CC BY 4.0。評価用途を想定しており、学習データとしての利用は控えてほしい(お願いであり、ライセンス上の制限ではない)
- Laya 日本語実測の全生データと再現コマンド(
docs/baseline_ja.md)
参考
- TypeSafe 公式ドキュメント: https://docs.typesafe.ai
- Laya モデルカード: https://huggingface.co/convaiinnovations/laya
- Laya Issue #131 / PR #259: https://github.com/NandhaKishorM/laya
- LocalJev: https://github.com/githubnext/localjev
- ModernBERT-Ja: https://huggingface.co/sbintuitions/modernbert-ja-310m
- ModernBERT 論文: https://arxiv.org/abs/2412.13663
訂正履歴
-
2026/09/26
- Jev の公開時期を「2026 年 5 月」から「2026 年 9 月 15 日(早期アクセス)」に訂正。「公開から数ヶ月で」を「1 週間ほどで」に訂正
- sokudan の設計説明を cross-attention から joint encoding に訂正し、「cross-attention をやめた理由」の節を追加
- 「一日でやったらどうなったか」を v0.0 の結果と明示し、「v0.1 でどうなったか」を追加
- 「公開したもの」に学習済みモデルと bench_en を追加。bench_ja の利用条件の文言をリポジトリの表記に合わせて修正
- 位置バイアスの上流への報告(Issue #131、PR #259)を追記

