modernbert-ja-130m-typo-detector
日本語の文の誤字、とくに誤変換(「以外と使いやすい」の「以外」)と、音声入力の聞き違い(「誤変換」→「5変換」)の箇所を、トークンごとの確率で示すモデルです。sbintuitions/modernbert-ja-130m を、トークン分類(OK / TYPO)でファインチューニングしました。Apple Neural Engine で動く Core ML 版も同梱しています。英語の要約は末尾にあります。
モデルの詳細
モデルの説明
- 開発: umiyosh(校正アプリ Kotobae の端末上の誤変換チェックとして)
- 種類: トークン分類(ModernBERT、約 1.3 億パラメーター)。出力はトークンごとの P(TYPO)
- 言語: 日本語
- ライセンス: MIT
- 元のモデル: sbintuitions/modernbert-ja-130m(MIT)
版
| 版 | リビジョン | 変えたこと |
|---|---|---|
| 2026-10-26 版(今の版) | 33115ea |
人工のかな漢字変換の取り違えで下地学習させた重みを、2026-10-21 版と半分ずつ混ぜた |
| 2026-10-21 版 | c548fa9 |
音声認識の書き起こしの誤りでも学習させた |
| 最初の版 | 2bf8db3 |
入力した文の誤変換(JWTD と人工の誤り)で学習させた |
古い版は、リビジョンを指定すれば使えます。
出どころ
- 学習・評価のコード: umiyosh/modernbert-ja-ondevice(最初の版は
training/、音声入力の誤りはasr/) - 評価の取り決め:
asr/PROTOCOL.md(学習の前に書き、試験データを開ける前に追記した) - 学習の推移と最終評価のページ: https://umiyosh.github.io/modernbert-ja-ondevice/
使い道
そのまま使う
日本語の文を 1 文ずつ入れ、誤りらしいトークンを見つけます。単体で印を付けるより、怪しい語を絞る前段として、候補の採点役 umiyosh/modernbert-ja-130m-homophone-scorer と組み合わせると最もよく働きます。
組み込んで使う
Kotobae は、このモデルで P(TYPO) が 0.05 以上の語だけ候補(同音語・取り違え表 umiyosh/jwtd-misconversion-table)を採点し、検出器 0.995 以上の箇所か、候補が書かれた語より 7.0 以上ありそうな箇所に印を付けます。候補を入れた文をこのモデルで確かめ直し、その差を候補の差に足します。
向かない使い方
- 誤りを直すこと(このモデルは場所を示すだけで、直した語は出さない)
- 日本語以外の文、長い文書をまとめて入れること(学習は 64 トークンまでの 1 文単位)
- 音声がないと決められない取り違え(「自己」と「事故」のように、どちらでも文が通るもの)の判定
偏り・リスク・限界
- 文字だけで判定する: どちらの語でも文が通る取り違えは、原理的に見分けられません。
- 音声認識と文体が変わると下がる: Whisper で書き起こした Common Voice の読み上げで選んだ閾値です。ReazonSpeech で書き起こした FLEURS(Wikipedia の翻訳文)では、同音の取り違えの再現率が 66.3% から 42.9% に下がりました(#98 の前の組み合わせは 22.3%)。
- 誤った印: Common Voice の test の正しい書き起こしで 1,000 字に 1.05 個。試験の前に決めた上限 1.00 を 0.05 超えています(95% 区間 0.80〜1.32)。
- 学習データの偏り: JWTD は Wikipedia の文で、全角・改行なしで書かれています。半角の並びや改行に印が付くことがあります。Common Voice の読み上げは、読み手の年齢・性別・地域に偏りがあり得ます(話者の属性は使っていません)。
- 固有名詞: 人工の誤りに固有名詞の取り違えは入れていません。
勧めること
誤りの箇所を示す補助として使い、直すかどうかは人が決めてください。別の音声認識や文体に使うときは、その書き起こしで誤った印の数と再現率を測り直してください。
始め方
import torch
from transformers import AutoModelForTokenClassification, AutoTokenizer
name = "umiyosh/modernbert-ja-130m-typo-detector"
tok = AutoTokenizer.from_pretrained(name)
model = AutoModelForTokenClassification.from_pretrained(name).eval()
text = "このアプリは以外と使いやすい。"
enc = tok(text, return_offsets_mapping=True, return_tensors="pt")
offsets = enc.pop("offset_mapping")[0]
with torch.no_grad():
p = model(**enc).logits.softmax(-1)[0, :, 1] # P(TYPO) per token
for (s, e), q in zip(offsets.tolist(), p.tolist()):
if e > s and q >= 0.995:
print(text[s:e], round(q, 3))
閾値 0.995 は、Kotobae が候補の採点と組み合わせて使う値です(2026-10-21 版は 0.6)。この版は誤りの箇所の P が 1 の近くに集まるので、閾値も 1 の近くになります。単体で使うときの閾値は測っていません。1 文ずつ、<s> と </s> を付けて入力してください(上の例のとおり)。
Core ML
coreml/typo-detector-b32-l64.mlpackage は、input_ids と attention_mask(32 × 64、int32、足りない分は padding)を受け取り、p_typo(32 × 64、トークンごとの P(TYPO))を返します。Apple Silicon の Neural Engine で 32 行 66 ms、PyTorch 版との差は最大 0.004 です。Python(coremltools 9.0)から呼ぶときは PYTHONMALLOC=malloc を付けてください。付けないと、Core ML の裏のスレッドがメモリを解放するときに落ちることがあります。
学習
学習データ
| 出典 | 使い方 | ライセンス |
|---|---|---|
| sbintuitions/modernbert-ja-130m | 元のモデル | MIT |
| 日本語 Wikipedia 入力誤りデータセット(JWTD)v2 の train(京都大学 言語メディア研究室) | 誤りのある文と直した文(137 万行)。人工の誤りの元にした、直した文と誤りの組 | CC BY-SA 3.0 |
| 人工の誤り | JWTD の直した文 686,932 文に 1 か所ずつ誤りを入れたもの: JWTD の誤りの組を逆に当てる(303,234)、同音異義語(238,225)、音声入力のようなカタカナ書き(96,054)、ひらがなを同じ読みの漢字の名詞に(49,419) | JWTD から生成 |
| UniDic(unidic-lite、fugashi 経由) | 人工の誤りを作るための読み。モデルに辞書のデータは入っていない | BSD-3-Clause(UniDic)、MIT |
| Mozilla Common Voice 日本語 27.0 の train(2026-10-21 版から) | 音声を whisper-large-v3-turbo(MIT)で書き起こし、読み上げた文との差分を誤りとした約 5.6 万文。評価に使う話者・文は除いた | CC0 |
| JWTD v2 train の直した文の読み上げ(2026-10-21 版から) | Kokoro-82M(Apache-2.0)で読み上げ、同じく書き起こした約 3.6 万文。評価に使う文は除いた | JWTD から生成 |
| yuuki14202028/kanakanji-edge-33m(2026-10-26 版) | 人工のかな漢字変換の取り違えを作るための変換。モデルに変換モデルの重みは入っていない | Apache-2.0 |
このモデルの重みは MIT ライセンスです。重みに JWTD・Common Voice の文や音声は含まれず、それらの再配布もしていません。評価に使う文は学習から除きました。Common Voice の話者・文・音声は、学習・検証・試験の間で重ならないように分けました(asr/leak_check.py)。
学習の手順
- 文字の差分で誤りの文字を求め、その文字を含むトークンを
TYPOとした - 最初の版: 全パラメーターのファインチューニング。AdamW(学習率 5e-5、weight decay 0.01)、バッチ 32、warmup 1,000 ステップの線形減衰、最大 64 トークン。1 エポック(64,332 ステップ)のうち、開発用の問題で選んだ 30,000 ステップのチェックポイント
- 2026-10-21 版: 最初の版から、上の 2 つの書き起こしの誤りで 4 つの乱数の種ごとに学習を続け(学習率 5e-5)、3,000・4,000・5,000 ステップの 12 個の重みを平均した。その平均を 3 割、最初の版を 7 割で混ぜた(入力した文の誤りを忘れないため)
- 2026-10-26 版: 2026-10-21 版から、人工のかな漢字変換の取り違え 15 万文(半分は取り違えなし)、正しい文 5.9 万文、上の書き起こしの誤りで下地学習(11,997 ステップ、学習率 2e-5。正しいトークンでは 2026-10-21 版の確率に合わせる蒸留を加えた)し、書き起こしの誤りで仕上げた(5,465 ステップ、学習率 1e-5)。その重みを 2026-10-21 版と半分ずつ混ぜた。人工の取り違えは、JWTD の直した文の語を、かな漢字変換モデルがその読みに出した別の漢字の同音語に置き換え、元のモデルで置き換えた語の方が不自然と採点されたものだけを残した(CSCD-NS の作り方、arXiv 2211.08788)。評価に使う文と 15 字重なる文は除いた
- 精度: float32 で学習(Apple Silicon の MPS)。Core ML 版は float16
評価
試験データ・条件・物差し
- 試験データ: Common Voice 27.0 日本語の公式 test から、学習・検証と話者・文が重ならないもの 8,520 件を Whisper で書き起こし、6,563 件(2,091 話者)を数えた。書き起こしが壊れたもの、読み手の言い違い(別系統の音声認識 ReazonSpeech k2 v2 も同じに聞いたもの)、報告された文は除いた。同音の取り違えは 523 件。試験データは、版と閾値をすべて決めた後に一度だけ開けた
- 外部データ: FLEURS 日本語(CC BY 4.0)の 3 分割すべてを ReazonSpeech k2 v2 で書き起こしたもの 2,638 件(1,574 文)。選択には使っていない
- 物差し: 再現率(本物の誤りのうち印が重なった割合。同音の取り違えと、すべての書き起こしの誤りの 2 つ)、適合率(誤りのある書き起こしに付けた印のうち、本物の誤りに重なった割合)、正しい書き起こし 1,000 字あたりの誤った印。95% 区間は話者単位のブートストラップ(1 万回、FLEURS は文単位)、差の p 値は話者単位の入れ替え検定
- 系: すべて Kotobae と同じ処理(Core ML)。閾値は検証用の話者を 2 つに分け、片方で選んだ点をもう片方に当てて決めた(検出器 0.995、候補の差 7.0。どちらの半分で選んでも同じ点)
結果
Common Voice の test(報告):
再現率は、本物の誤りのうち印が重なった割合です。適合率は、誤りのある書き起こしに付けた印のうち、本物の誤りに重なった割合です。正しい書き起こしに付けた印は、適合率とは別に 1,000 字あたりで示します。
| 系 | 同音の取り違えの再現率 | すべての誤りの再現率 | 適合率 | 誤った印 / 1,000 字 |
|---|---|---|---|---|
| この版と homophone-scorer の 2026-10-26 版 | 66.3%(61.9〜70.6) | 21.5% | 93.5% | 1.05(0.80〜1.32) |
最初の版(2bf8db3)と modernbert-ja-130m-coreml |
22.0% | 8.8% | 81.0% | 0.88 |
| 同じ候補を学習なしの東北大 BERT で採点(藤井・新納 2021 の方式) | 41.3% | 19.2% | 95.0% | 0.98 |
| Jev(文節ごとに誤りを問う商用 API) | 23.7% | 28.8% | 85.9% | 1.89 |
| 規則だけ(取り違え表と未知語) | 58.1% | 30.2% | 33.1% | 60.35 |
最初の版との差は、同音の取り違えで +44.4 ポイント、すべての誤りで +12.7 ポイント(どちらも p < 0.001)。誤った印の差(+0.18)は有意ではありません(p = 0.25)。
FLEURS(報告): 同音の取り違えの再現率 42.9%(35.1〜50.8)、すべての誤りの再現率 17.6%、適合率 93.3%、誤った印 0.42。最初の版は 22.3%・9.1%・80.0%・0.33。
まとめ
音声入力の同音の取り違えの再現率は、最初の版の 22.0% から 66.3% に上がりました。目標は「誤った印 1,000 字に約 1 個で 60%」で、試験の前に書いた判定(誤った印 1.00 以下)は 0.05 超えています。別の音声認識と書き言葉の文では 42.9% で、伸びは持ち越せますが水準は下がります。
選択に使った値(参考)
検証用の話者の 2 つの半分で選んだときの値です。版を選ぶのに両方の半分を使ったので、少し良く見えている可能性があります。
| 測ったもの | 2026-10-21 版の組み合わせ | この版の組み合わせ |
|---|---|---|
| 本物の音声入力の同音の聞き違いの再現率(566 件、2 つの半分を合わせて) | — | 62.7% |
| 同じく、選択に使っていない半分 | 51.1% | 60.7% |
| Common Voice の正しい書き起こしへの印(1,000 字あたり、2 つの半分) | — | 0.98 / 0.99 |
| JWTD test の正しい文 150,007 字への印 | 164 | 170 |
最初の版は、入力した文の誤変換(JWTD v2 の test と人工の誤り)で、正しい文 60 本への印を 1,000 字に 1 個以下に抑える閾値のとき、候補の採点と組み合わせた再現率が held-out 72%・fresh 67% でした(単体では 52%・49%、recruit-jp/japanese-typo-detector-roberta-base は 46%・43%)。この評価データは JWTD の文と非公開の文が混ざるため公開していません。
環境への影響
- ハードウェア: Apple MacBook Pro(Apple M4 Pro、メモリー 48 GB)。学習は MPS、評価は Core ML
- 時間: 最初の版の 1 エポックが約 10 時間。2026-10-26 版の下地学習が約 3 時間。そのほかの学習の時間は記録していない
- クラウド: 使っていない(手元の Mac だけ)
- 排出量: 測っていない
技術仕様
- 構造と目的: ModernBERT(modernbert-ja-130m)にトークン分類の頭を付け、各トークンが誤りの一部か(
TYPO)を学ばせた - ソフトウェア: PyTorch 2.14、transformers 5.19、coremltools 9.0
引用
学習データの JWTD:
田中佑, 村脇有吾, 河原大輔, 黒橋禎夫. 日本語 Wikipedia の編集履歴に基づく入力誤りデータセットと訂正システムの改良. 言語処理学会第27回年次大会, 2021.
モデルカードの作者・連絡先
umiyosh。質問や不具合は GitHub の Issue へ。
English
A Japanese typo detector for kanji misconversions and voice-input mishearings: sbintuitions/modernbert-ja-130m fine-tuned for token classification (OK / TYPO), with a Core ML package for the Apple Neural Engine (coreml/). MIT. Training progress and final evaluation: page. Code and evaluation protocol: umiyosh/modernbert-ja-ondevice.
- Versions: the first version (
2bf8db3) was trained on the Japanese Wikipedia Typo Dataset v2 train split (CC BY-SA 3.0, not redistributed) plus 686,932 synthetic errors. The 2026-10-21 version (c548fa9) was further trained on speech-recognition errors (Whisper large-v3-turbo transcripts of Mozilla Common Voice Japanese 27.0 train clips, CC0, and of Kokoro-82M readings of JWTD sentences). The 2026-10-26 version (33115ea, current) averages that version half and half with a retraining pretrained on 150,000 synthetic kana-kanji misconversions made with kanakanji-edge-33m (Apache-2.0). - Use: feed one sentence at a time with
<s>and</s>. It works best as the first stage of candidate scoring with umiyosh/modernbert-ja-130m-homophone-scorer: Kotobae scores the alternatives of words at P ≥ 0.05, checks each alternative in place with this detector, and marks at P ≥ 0.995 or a lead of 7.0. It locates errors and does not correct them. - Evaluation: measured once on Common Voice test (6,563 clips of 2,091 speakers kept apart from training, 523 homophone errors) after every choice was fixed: 66.3% of homophone errors (95% CI 61.9–70.6, speaker bootstrap) at 1.05 false marks per 1,000 characters of correct transcripts, against 22.0% for the first version with the untrained scorer (p < 0.001); 93.5% of its marks on transcripts with errors fall on an error (precision). The goal was 60% at about one false mark per 1,000 characters; the judgment written before test said at most 1.00. On FLEURS ja transcribed with ReazonSpeech, it finds 42.9% (first version: 22.3%).
- Limits: text only, so a wrong word that also fits the sentence (自己 / 事故) cannot be told apart; the level drops with another recognizer and written text; half-width runs and line breaks can draw marks.