--- language: - ja license: cc-by-sa-4.0 library_name: transformers pipeline_tag: token-classification tags: - token-classification - ner - japanese - tts - g2p - openjtalk - modernbert - yomi-linter base_model: sbintuitions/modernbert-ja-130m datasets: - stockmark/ner-wikipedia-dataset metrics: - f1 widget: - text: "潤羽るしあの配信で魔王魂の楽曲が流れた" example_title: "ニッチ固有名詞(VTuber 名 / フリー BGM レーベル)" - text: "蜂窩織炎の症状が出た患者に冠動脈瘤の検査も実施した" example_title: "漢字専門語(医療)" - text: "PyTorch で学習した LangChain アプリを Anthropic に繋いだ" example_title: "英字固有名詞(技術記事)" - text: "令和7年、徳井さんが新機能を発表した" example_title: "人名(日本語固有名詞)" --- # yomi-linter: 日本語 TTS の誤読プリフライト用 ModernBERT-Ja [ModernBERT-Ja-130m](https://huggingface.co/sbintuitions/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`](https://huggingface.co/datasets/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 が誤読しそうな固有名詞・未知語のスパンを返します。スコープは **検出のみ** で、正しい読みの付与・音声合成本体・配信統合は対象外です。 ```text 入力: 潤羽るしあの配信で魔王魂の楽曲が流れた 出力: [ {"surface": "潤羽るしあの", "start": 0, "end": 6, "label": "RISK", "score": 1.0}, {"surface": "魔王魂", "start": 9, "end": 12, "label": "RISK", "score": 0.999} ] ``` ## 使い方 ブラウザでそのまま試したい方は、Hugging Face Space にデモを用意しています(インストール不要・例文 4 つ収録)。 - Demo: 手元から使う場合は、`transformers` のトークン分類パイプラインから直接利用できます。 ```python 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 のままで、ロード時にクライアント側で量子化します。 ```python 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`](https://huggingface.co/datasets/stockmark/ner-wikipedia-dataset)(CC BY-SA 4.0) + 漢字真誤読 118 語 ## 引用 ```bibtex @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} } ```