yomi-linter: 日本語 TTS の誤読プリフライト用 ModernBERT-Ja
ModernBERT-Ja-130m を BIO トークン分類で fine-tune したモデルで、日本語 TTS(特に OpenJTalk のような G2P / 辞書ベース TTS)が誤読しがちな固有名詞・未知語のスパンを 合成前に 検出します。
- タスク: トークン分類(BIO 二値:
O/B-RISK/I-RISK) - ベース:
sbintuitions/modernbert-ja-130m(MIT) - 学習データ: 著者ブログ(自身が著作者)+
stockmark/ner-wikipedia-dataset(CC BY-SA 4.0)+ 漢字専門語 118 語の弱ラベル注入 - 対応 TTS: OpenJTalk / piper-plus / VOICEVOX など G2P / 辞書ベース TTS
- 未検証: VALL-E / GPT-SoVITS / CosyVoice 等の LLM エンドツーエンド TTS は対象外(別の誤読パターンを持つため)
できること
入力した日本語文から TTS が誤読しそうな固有名詞・未知語のスパンを返します。スコープは 検出のみ で、正しい読みの付与・音声合成本体・配信統合は対象外です。
入力: 潤羽るしあの配信で魔王魂の楽曲が流れた
出力: [
{"surface": "潤羽るしあの", "start": 0, "end": 6, "label": "RISK", "score": 1.0},
{"surface": "魔王魂", "start": 9, "end": 12, "label": "RISK", "score": 0.999}
]
使い方
ブラウザでそのまま試したい方は、Hugging Face Space にデモを用意しています(インストール不要・例文 4 つ収録)。
手元から使う場合は、transformers のトークン分類パイプラインから直接利用できます。
from transformers import AutoTokenizer, AutoModelForTokenClassification, pipeline
model_id = "ayousanz/yomi-linter-modernbert-ja-130m"
tok = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForTokenClassification.from_pretrained(model_id)
ner = pipeline(
"token-classification",
model=model,
tokenizer=tok,
aggregation_strategy="simple",
)
for span in ner("潤羽るしあの配信で魔王魂の楽曲が流れた"):
print(f"{span['word']:10s} {span['entity_group']:5s} score={span['score']:.3f}")
出力例:
潤羽るしあの RISK score=1.000
魔王魂 RISK score=0.999
動的量子化(INT8, CPU 専用)
CPU 推論向けに PyTorch 動的量子化(nn.Linear のみ INT8 化)が使えます。配布ウェイトは float のままで、ロード時にクライアント側で量子化します。
import torch
from torch.ao.quantization import quantize_dynamic
model_q = quantize_dynamic(model, {torch.nn.Linear}, dtype=torch.qint8)
| バリアント | サイズ | CPU ms/文 | 漢字実誤読 recall |
|---|---|---|---|
| 130m float(本モデル) | 505 MB | 63 | 80% |
| 130m INT8(動的量子化) | 277 MB | 39 | 80% |
評価
評価指標は 「OpenJTalk が実際に誤読する固有名詞・専門語の合成前検出 recall」 です。span-F1 のようなラベル一致度ではなく、実用に効くかを測る本命指標としてこれを採用しています。
| 比較対象 | 純日本語固有名詞 | 漢字専門語(医療含む) |
|---|---|---|
| OpenJTalk + 公開読み辞書のみ | 14% | ― |
| 漢字弱ラベルなし(従来モデル) | 71–100% | 47% |
| 本モデル(漢字弱ラベル 118 語あり) | 71–100% | 82% |
- 医療ドメイン: 0/6 → 5/6(漢字弱ラベル注入の効き)
- blog overlap: 0.62 → 0.63(微増)
- wiki overlap: 0.97 を維持(汎用 NER 退行なし)
- silver eval span-F1: 0.921
学習
- 設定: lr=1e-5 / 4 epoch / batch 16(grad-accum 2)/ max_len 128
- 環境: NVIDIA RTX A6000(Shadeform)× 5 分 48 秒(計 $0.26)
- 手法: ブログコーパス + stockmark ner-wikipedia を BIO トークン分類で fine-tune し、漢字真誤読 118 語をキャリア文 107 文に弱ラベル注入
学習データの作り方の概要は著者ブログで公開予定です。
制限事項
- 対象 TTS: OpenJTalk・piper-plus・VOICEVOX など G2P / 辞書ベース TTS。LLM エンドツーエンド TTS(VALL-E・GPT-SoVITS・CosyVoice 系など)への適用は未検証 です。
- 漢字専門語の取りこぼし:
冠動脈瘤のような医療熟語の一部はまだ完全には拾えません(漢字穴は 83% 縮小・1/6 程度の残あり)。 - 多音字(文脈で読みが割れる語)は v1 対象外: 「日本=にほん/にっぽん」「行った=いった/おこなった」のような文脈依存読みは別アイデアとして扱っていません。
- 読みは付与しません: 本モデルは「どこが事故りそうか」の 検出のみ。正しい読みの付与は OpenJTalk user_dict / cc-g2pnp など別レイヤーの仕事です。
ライセンスとデータソース
- ライセンス: CC BY-SA 4.0
- ベース:
sbintuitions/modernbert-ja-130m(MIT) - 学習データ: 著者ブログ +
stockmark/ner-wikipedia-dataset(CC BY-SA 4.0) + 漢字真誤読 118 語
引用
@software{yomi_linter_2026,
author = {yousan},
title = {yomi-linter: ModernBERT-Ja for Japanese TTS misreading pre-flight},
year = {2026},
url = {https://huggingface.co/ayousanz/yomi-linter-modernbert-ja-130m}
}