ModernBERT-Ja pure-NN Japanese G2P research project — no dict lookup in inference. Phase 0-2 baseline reproduction and 2-arch pilot (seq2seq / char-BERT) results.
Python
9
25 commits
updated Oct 1, 2026
ModernBERT-Ja をベースに、推論時に辞書 lookup を一切呼ばない pure-NN の日本語 G2P (Grapheme-to-Phoneme) を試した研究プロジェクトです。
方針としては pyopenjtalk / OpenJTalk のような辞書 + ルール、あるいは haqumei のような hybrid ではなく、テキストを直接 neural network に入力して音素列を得る構成を採ります。学習時に辞書由来の教師信号を使うことは許容しますが、推論パスに MeCab / UniDic / 辞書 lookup を含めません。
Phase 0 (baseline 再現) と Phase 2 (2 アーキ並列 pilot 学習・評価) までを実施し、その結果を本 README に記録しています。Phase 3 (マルチタスク学習) 以降はコード未着手です。
pure-NN 制約下で 2 種類のアーキテクチャを並列学習し、JSUT Basic5000 / JVS-3000 / ROHAN 4600 / hard-set (140 文) の 4 dataset で評価しました。
| Pilot | JSUT PER | JVS CER | ROHAN KER | hard-set PER |
|---|---|---|---|---|
| 30K (3 seeds mean ± σ) | 64.55 ± 2.64 % | 72.00 ± 3.96 % | 67.17 ± 4.73 % | 49.34 ± 0.51 % |
| 60K (2 seeds mean ± σ) | 66.44 ± 0.61 % | 75.90 ± 0.96 % | 71.86 ± 2.14 % | 49.92 ± 1.18 % |
| Δ (60K − 30K) | +1.89 | +3.90 | +4.69 | +0.58 |
| 30K best seed (20260706) | 62.41 % | 67.85 % | 63.15 % | 49.24 % |
| Pilot | JSUT | JVS | ROHAN | hard-set |
|---|---|---|---|---|
| v2 (pad_class_weight=2.0) | 99.97 % | 99.97 % | 100.00 % | 99.04 % |
| v3 (pad_class_weight=1.0) | 99.98 % | 99.96 % | 100.00 % | 98.91 % |
char-BERT は eval で 99% 以上に collapse。pad_class_weight を弱めても復旧しませんでした。
| モデル | パラメータ | JSUT PER | プロトコル |
|---|---|---|---|
| CharsiuG2P byT5 (多言語) | 300M | 10.51 % | 自著 held-out (単語単位) |
| CharsiuG2P monolingual JA-only | 300M | 66.89 % | 自著 held-out |
| Kakegawa TJ-G2P | ~110M | 11.85 % | JSUT400 (400 文 subset) |
| 本 seq2seq 30K best | 157M | 62.41 % | JSUT Basic5000 (5000 文) |
| 本 seq2seq 30K mean | 157M | 64.55 % | JSUT Basic5000 |
| haqumei (hybrid, 参考) | — | 1.17 % | JSUT Basic5000 |
CharsiuG2P monolingual (66.89%) は 4.5pt 上回りましたが、多言語版 (10.51%) には 52pt 及ばず、先行 pure-NN 4 モデル全てを 3 本柱で越える当初目標は達成できていません。
| Category | n | per_micro |
|---|---|---|
| proper_noun (kanji/katakana 混合) | 20 | 39.30 % |
| counter (助数詞) | 20 | 43.80 % |
| polyphone (多音字) | 20 | 47.11 % |
| loanword (カタカナ外来語) | 20 | 48.90 % |
| english_abbreviation | 20 | 50.00 % |
| numeric_unit (数詞・単位) | 20 | 54.37 % |
| english_mixed | 20 | 56.83 % |
英単語混在が最も苦手 (56.83%)、固有名詞は curated 短文の中では相対的に得意 (39.30%)。
ModernBERT-ja のトークナイザーは SentencePiece 系の subword で、SB Intuitions 自身が HF カードで「token classification タスクでは性能が悪い」と明記しています。そのため各文字にラベルを付ける naive token classification は最初から避け、次の 2 通りを並列に走らせて比較しました。
base LM を統一した A/B ではなく「ModernBERT で行く」vs 「char-level BERT に切り替える」の trade-off 比較になっています。
pyopenjtalk-plus 辞書 + UniDic + Wikipedia + Aozora + JMDict の 5 source から (surface, phoneme) の pair を抽出し、統合コーパスを構築しました。
Wikipedia は並列 ingest infra、Aozora は per-ruby emission (per-file → per-ruby で 300 倍増加)、UniDic は 33 列の実 CSV に合わせた parser で処理しています。
uv venv --python 3.12 .venv
source .venv/bin/activate
uv pip install -e ".[dev,baselines]" # haqumei / pyopenjtalk-plus は baselines extra
# JSUT-label を取得
git clone --depth 1 https://github.com/prj-beatrice/jsut-label.git
# haqumei の JSUT Basic5000 PER (公式 1.17%) を再現
JSUT_YAML=./jsut-label/text_kana/basic5000.yaml \
python scripts/eval_haqumei_jsut.py
期待出力: PER 1.1657% (公式 1.17% との差 0.005 pt、AC-P0 要件 ≤ 0.1% を満たす)。
uv pip install -e ".[training,pipeline]" # Parquet 読み込みに pyarrow (pipeline extra) が必要
# seq2seq (30K steps)
python -m modernbert_g2p train --config configs/p_a_30k.yaml --seed 20260706
# char-BERT (30K steps)
python -m modernbert_g2p train --config configs/p_c_30k_v2.yaml --seed 20260706
python -m modernbert_g2p eval --pilot P-A --config configs/p_a_30k.yaml \
--checkpoint reports/phase2/p_a_30k/20260706/checkpoint_step_30000.pt \
--dataset jsut --output reports/phase2/eval/p_a_20260706_jsut.json
pytest -q
scripts/eval_haqumei_jsut.py と bit-一致プロトコル)JVS / ROHAN 用に、モデルの JULIUS phoneme 出力を katakana に変換する converter (src/modernbert_g2p/evaluation/phoneme_to_kana.py) を実装しています。CV / digraph / palatalized 音素、moraic N (ン)、geminate q (ッ)、長音 (ー) をカバーする state machine で、unit test 26 ケース全て pass しています。
modern-bert-g2p/
├── src/modernbert_g2p/ # ソースコード
│ ├── metrics/ # PER / CER / KER canonical 実装
│ ├── models/ # seq2seq / char-BERT アーキテクチャ
│ ├── training/ # 学習ループ + collator
│ ├── evaluation/ # phoneme_to_kana converter
│ └── data/ # 5-source データパイプライン
├── tests/ # pytest スイート (529 tests)
├── scripts/ # baseline 測定・データ生成の CLI
├── configs/ # Phase 2 pilot YAML (p_a_30k / p_c_30k_v2 等)
├── docs/
│ ├── requirements.md # 要求定義書 (FR/NFR/CR/AC)
│ ├── research/ # 9 本の技術ドキュメント
│ └── design/ # Phase 別実装設計
├── reports/phase2/eval/ # Phase 2 全 eval JSON (50 files)
├── data/ # (gitignored) raw / processed
├── pyproject.toml
└── README.md
pyproject.toml でランタイムと optional extras に分離しています。
dependencies): pyyaml, numpy — metrics / evaluation に必要な最小構成optional-dependencies.baselines): haqumei==0.8.0, pyopenjtalk-plus, jiwer>=3, tqdm — scripts/eval_*.py の baseline 測定で使用optional-dependencies.training): torch>=2.1, transformers>=4.48, wandb, omegaconf, fugashi[unidic] — Phase 2 以降で使用 (uv.lock の解決版は torch 2.12.1 / transformers 5.13.0)optional-dependencies.phase2): fugashi>=1.3, unidic-lite>=1.0optional-dependencies.pipeline): pyarrow>=15, lxml>=5 — Parquet 入出力optional-dependencies.dev): pytest>=8, ruff, mypy, ipythonPython サポート: >=3.10,<3.13 (haqumei 0.8.0 は 3.13/3.14 未対応)。
詳細は CLAUDE.md と docs/requirements.md を参照。
詳細は CLAUDE.md 参照。
CLAUDE.md — プロジェクト方針、pure-NN 制約、v2.0 pivot 経緯docs/requirements.md — 要求定義書 (FR/NFR/CR/AC 付き)docs/research/01_overview.md — サマリーと開発戦略docs/research/02_existing_systems.md — 既存 G2P サーベイdocs/research/06_implementation_roadmap.md — v2.0 実装ロードマップdocs/research/07_nn_only_benchmarks.md — pure-NN 先行研究の徹底調査docs/research/09_pure_nn_g2p_benchmarks.md — 越えるべき pure-NN 4 モデルの整理reports/phase2/eval/pilot_table.md — Phase 2 の full 数値表 (v4)Apache License 2.0 (LICENSE)。
学習・評価に用いる第三者データセット (pyopenjtalk-plus 辞書, UniDic, JSUT, ROHAN, JMDict, Wikipedia 等) はそれぞれ別ライセンス (BSD / MIT / CC-BY-4.0 / CC-BY-SA-4.0 等) が適用されます。特に Share-Alike 系ライセンスは重み配布時に影響するため、重み公開前に一次資料の再確認が必要です。
746 followers · starred Jul 2026
ModernBERT-Ja pure-NN Japanese G2P research project — no dict lookup in inference. Phase 0-2 baseline reproduction and 2-arch pilot (seq2seq / char-BERT) results.
Python
9
25 commits
updated Oct 1, 2026
ModernBERT-Ja をベースに、推論時に辞書 lookup を一切呼ばない pure-NN の日本語 G2P (Grapheme-to-Phoneme) を試した研究プロジェクトです。
方針としては pyopenjtalk / OpenJTalk のような辞書 + ルール、あるいは haqumei のような hybrid ではなく、テキストを直接 neural network に入力して音素列を得る構成を採ります。学習時に辞書由来の教師信号を使うことは許容しますが、推論パスに MeCab / UniDic / 辞書 lookup を含めません。
Phase 0 (baseline 再現) と Phase 2 (2 アーキ並列 pilot 学習・評価) までを実施し、その結果を本 README に記録しています。Phase 3 (マルチタスク学習) 以降はコード未着手です。
pure-NN 制約下で 2 種類のアーキテクチャを並列学習し、JSUT Basic5000 / JVS-3000 / ROHAN 4600 / hard-set (140 文) の 4 dataset で評価しました。
| Pilot | JSUT PER | JVS CER | ROHAN KER | hard-set PER |
|---|---|---|---|---|
| 30K (3 seeds mean ± σ) | 64.55 ± 2.64 % | 72.00 ± 3.96 % | 67.17 ± 4.73 % | 49.34 ± 0.51 % |
| 60K (2 seeds mean ± σ) | 66.44 ± 0.61 % | 75.90 ± 0.96 % | 71.86 ± 2.14 % | 49.92 ± 1.18 % |
| Δ (60K − 30K) | +1.89 | +3.90 | +4.69 | +0.58 |
| 30K best seed (20260706) | 62.41 % | 67.85 % | 63.15 % | 49.24 % |
| Pilot | JSUT | JVS | ROHAN | hard-set |
|---|---|---|---|---|
| v2 (pad_class_weight=2.0) | 99.97 % | 99.97 % | 100.00 % | 99.04 % |
| v3 (pad_class_weight=1.0) | 99.98 % | 99.96 % | 100.00 % | 98.91 % |
char-BERT は eval で 99% 以上に collapse。pad_class_weight を弱めても復旧しませんでした。
| モデル | パラメータ | JSUT PER | プロトコル |
|---|---|---|---|
| CharsiuG2P byT5 (多言語) | 300M | 10.51 % | 自著 held-out (単語単位) |
| CharsiuG2P monolingual JA-only | 300M | 66.89 % | 自著 held-out |
| Kakegawa TJ-G2P | ~110M | 11.85 % | JSUT400 (400 文 subset) |
| 本 seq2seq 30K best | 157M | 62.41 % | JSUT Basic5000 (5000 文) |
| 本 seq2seq 30K mean | 157M | 64.55 % | JSUT Basic5000 |
| haqumei (hybrid, 参考) | — | 1.17 % | JSUT Basic5000 |
CharsiuG2P monolingual (66.89%) は 4.5pt 上回りましたが、多言語版 (10.51%) には 52pt 及ばず、先行 pure-NN 4 モデル全てを 3 本柱で越える当初目標は達成できていません。
| Category | n | per_micro |
|---|---|---|
| proper_noun (kanji/katakana 混合) | 20 | 39.30 % |
| counter (助数詞) | 20 | 43.80 % |
| polyphone (多音字) | 20 | 47.11 % |
| loanword (カタカナ外来語) | 20 | 48.90 % |
| english_abbreviation | 20 | 50.00 % |
| numeric_unit (数詞・単位) | 20 | 54.37 % |
| english_mixed | 20 | 56.83 % |
英単語混在が最も苦手 (56.83%)、固有名詞は curated 短文の中では相対的に得意 (39.30%)。
ModernBERT-ja のトークナイザーは SentencePiece 系の subword で、SB Intuitions 自身が HF カードで「token classification タスクでは性能が悪い」と明記しています。そのため各文字にラベルを付ける naive token classification は最初から避け、次の 2 通りを並列に走らせて比較しました。
base LM を統一した A/B ではなく「ModernBERT で行く」vs 「char-level BERT に切り替える」の trade-off 比較になっています。
pyopenjtalk-plus 辞書 + UniDic + Wikipedia + Aozora + JMDict の 5 source から (surface, phoneme) の pair を抽出し、統合コーパスを構築しました。
Wikipedia は並列 ingest infra、Aozora は per-ruby emission (per-file → per-ruby で 300 倍増加)、UniDic は 33 列の実 CSV に合わせた parser で処理しています。
uv venv --python 3.12 .venv
source .venv/bin/activate
uv pip install -e ".[dev,baselines]" # haqumei / pyopenjtalk-plus は baselines extra
# JSUT-label を取得
git clone --depth 1 https://github.com/prj-beatrice/jsut-label.git
# haqumei の JSUT Basic5000 PER (公式 1.17%) を再現
JSUT_YAML=./jsut-label/text_kana/basic5000.yaml \
python scripts/eval_haqumei_jsut.py
期待出力: PER 1.1657% (公式 1.17% との差 0.005 pt、AC-P0 要件 ≤ 0.1% を満たす)。
uv pip install -e ".[training,pipeline]" # Parquet 読み込みに pyarrow (pipeline extra) が必要
# seq2seq (30K steps)
python -m modernbert_g2p train --config configs/p_a_30k.yaml --seed 20260706
# char-BERT (30K steps)
python -m modernbert_g2p train --config configs/p_c_30k_v2.yaml --seed 20260706
python -m modernbert_g2p eval --pilot P-A --config configs/p_a_30k.yaml \
--checkpoint reports/phase2/p_a_30k/20260706/checkpoint_step_30000.pt \
--dataset jsut --output reports/phase2/eval/p_a_20260706_jsut.json
pytest -q
scripts/eval_haqumei_jsut.py と bit-一致プロトコル)JVS / ROHAN 用に、モデルの JULIUS phoneme 出力を katakana に変換する converter (src/modernbert_g2p/evaluation/phoneme_to_kana.py) を実装しています。CV / digraph / palatalized 音素、moraic N (ン)、geminate q (ッ)、長音 (ー) をカバーする state machine で、unit test 26 ケース全て pass しています。
modern-bert-g2p/
├── src/modernbert_g2p/ # ソースコード
│ ├── metrics/ # PER / CER / KER canonical 実装
│ ├── models/ # seq2seq / char-BERT アーキテクチャ
│ ├── training/ # 学習ループ + collator
│ ├── evaluation/ # phoneme_to_kana converter
│ └── data/ # 5-source データパイプライン
├── tests/ # pytest スイート (529 tests)
├── scripts/ # baseline 測定・データ生成の CLI
├── configs/ # Phase 2 pilot YAML (p_a_30k / p_c_30k_v2 等)
├── docs/
│ ├── requirements.md # 要求定義書 (FR/NFR/CR/AC)
│ ├── research/ # 9 本の技術ドキュメント
│ └── design/ # Phase 別実装設計
├── reports/phase2/eval/ # Phase 2 全 eval JSON (50 files)
├── data/ # (gitignored) raw / processed
├── pyproject.toml
└── README.md
pyproject.toml でランタイムと optional extras に分離しています。
dependencies): pyyaml, numpy — metrics / evaluation に必要な最小構成optional-dependencies.baselines): haqumei==0.8.0, pyopenjtalk-plus, jiwer>=3, tqdm — scripts/eval_*.py の baseline 測定で使用optional-dependencies.training): torch>=2.1, transformers>=4.48, wandb, omegaconf, fugashi[unidic] — Phase 2 以降で使用 (uv.lock の解決版は torch 2.12.1 / transformers 5.13.0)optional-dependencies.phase2): fugashi>=1.3, unidic-lite>=1.0optional-dependencies.pipeline): pyarrow>=15, lxml>=5 — Parquet 入出力optional-dependencies.dev): pytest>=8, ruff, mypy, ipythonPython サポート: >=3.10,<3.13 (haqumei 0.8.0 は 3.13/3.14 未対応)。
詳細は CLAUDE.md と docs/requirements.md を参照。
詳細は CLAUDE.md 参照。
CLAUDE.md — プロジェクト方針、pure-NN 制約、v2.0 pivot 経緯docs/requirements.md — 要求定義書 (FR/NFR/CR/AC 付き)docs/research/01_overview.md — サマリーと開発戦略docs/research/02_existing_systems.md — 既存 G2P サーベイdocs/research/06_implementation_roadmap.md — v2.0 実装ロードマップdocs/research/07_nn_only_benchmarks.md — pure-NN 先行研究の徹底調査docs/research/09_pure_nn_g2p_benchmarks.md — 越えるべき pure-NN 4 モデルの整理reports/phase2/eval/pilot_table.md — Phase 2 の full 数値表 (v4)Apache License 2.0 (LICENSE)。
学習・評価に用いる第三者データセット (pyopenjtalk-plus 辞書, UniDic, JSUT, ROHAN, JMDict, Wikipedia 等) はそれぞれ別ライセンス (BSD / MIT / CC-BY-4.0 / CC-BY-SA-4.0 等) が適用されます。特に Share-Alike 系ライセンスは重み配布時に影響するため、重み公開前に一次資料の再確認が必要です。
746 followers · starred Jul 2026