Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

英語をそれっぽく読み上げられるようにする(OpenJTalkの出力に対して後処理して日本語モーラに変換する案) #1524

Open
Hiroshiba opened this issue Feb 4, 2025 · 12 comments
Assignees
Labels
機能向上 状態:実装者募集 実装者を募集している状態 状態:設計 設計をおこなっている状態

Comments

@Hiroshiba
Copy link
Member

内容

英単語をそれっぽく自然に読ませたいという需要があります。
英単語辞書を追加する案がありましたが、容量増大や英大文字小文字の区別登録、リクエストごとにオンオフ切り替えしづらいなどの課題がありました。

新しい解決策を思いつきました!
OpenJTalkの出力に対し、未知語アルファベットのみに後処理をかけて日本語モーラに変換する方法であれば、これらの課題を迂回できそうです。

具体的には、フルコンテキストラベル取得後に、g2p-en を適用して英単語を音素に変換し、それをさらに何らかの規則で日本語モーラにマッピングする想定です。
英→日変換規則は既存の事例などを参照しながら検討することになりそう。
あと英単語の間に挿入されがちな pau の調整もできると良さそう!

Pros 良くなる点

  • 英単語辞書を別途大量に用意しなくても英語発音に対応できる
  • 容量増や英大文字小文字対応の二重登録などの手間が不要になる
  • リクエスト単位でオン/オフやフラグ制御がしやすい
  • 英単語の中間 pau 調整にも応用できるかもなので、より自然な英語発音につながる

Cons 悪くなる点

  • 英→日モーラ変換規則処理が必要
  • g2p-en のモデルダウンロードなど運用を考慮する必要がある

実現方法

  1. フルコンテキストラベル作成後に、ラベル中の未知アルファベット語を抽出
  2. g2p-en を使って英語音素へ変換
  3. 変換された英語音素を日本語モーラへマッピング
  4. (可能なら)pauの最適化
  5. 実際に動かしてみて出来栄えをチェックする
  6. g2p-en による辞書モデルダウンロードはビルド時または初回実行時に行う

AudioQuery にパラメータ追加したらリクエストごとに適用有無を制御できそう。そうすべきか・デフォルトのオンオフはでき次第かも。
g2p-en は初回実行時に辞書をダウンロードするようなので、pyopenjtalk 同様にビルド時ダウンロードだけ行う仕組みも必要になりそうです。

その他

もしうまく動作が確認できたらコア側に正式に実装する可能性もありそう。
でも g2p-en の DNN モデルが numpy を使っていそうなので、工数的に難しい点もあるかも。

意見や議論募集中です! 転ばぬ先の杖がほしい・・・!
そして実験してくださる方も募集中です!!! g2p-enを試すのはそんなに難しくないと思うのですが、英語音素→日本語モーラマッピングが難しそうだなーと思ってます!

@Hiroshiba Hiroshiba added 機能向上 状態:実装者募集 実装者を募集している状態 状態:設計 設計をおこなっている状態 labels Feb 4, 2025
@takana-v
Copy link
Member

私の方で、色々試してみたいと思います
(とりあえず自分をアサインしますが、引き続き意見や議論・実験など募集中です!)

@takana-v takana-v self-assigned this Feb 11, 2025
@Hiroshiba
Copy link
Member Author

@takana-v ありがとうございます!!よろしくお願いします!!!

@Hiroshiba
Copy link
Member Author

e2e-enはNLTKを使用していて、そのライセンス周りを調べたのでメモ。おそらく問題なし!

@sabonerune
Copy link
Contributor

  1. g2p-en による辞書モデルダウンロードはビルド時または初回実行時に行う

についての情報です。

g2p-enはインポート時にnltkの既定の場所にモデルがあるかどうか調べ、ない場合はダウンロードするという仕様になっています。
この動作はソースコードを変更しないと直せないと思います。

また、nltkに変更があったのか使用するデータが間違っているようです。
averaged_perceptron_taggerをインストールしていますが実行時にエラーが起こりaveraged_perceptron_tagger_engをダウンローするように求められます。

https://github.com/Kyubyong/g2p/blob/c6439c274c42b9724a7fee1dc07ca6a4c68a0538/g2p_en/g2p.py#L20-L27


nltk_dataの場所を変更する方法は

  • 環境変数NLTK_DATAを設定する
  • nltk.data.pathを変更する
  • (多分)使用しているnltkモジュールを手動で初期化するときに適切なパラメーターを渡す

等があると思います。

https://www.nltk.org/data.html#manual-installation


一応環境変数かnltk.data.pathの変更で辞書モデルダウンロードはビルド時または初回実行時に行うは達成可能ですがaveraged_perceptron_taggerの使用しないファイル分(約8MB)無駄が生じます。
完全に修正する場合はフォークが必要です

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Feb 11, 2025

@sabonerune 詳しくありがとうございます!!
とりあえず動きさえすれば(&そこそこ良い感じであれば)リリースできそうなのは良いですね・・・!
8MBを頑張るか微妙なところですが、可能なら削減したいのと、あと将来的にVOICEVOXに向けたチューニングやメンテナンスも必要な気もしているのと、なんかpyinstaller等に混ぜるときに別の問題とかも発生しそうなので、フォークすることになる気がしています・・・!

@Patchethium
Copy link
Contributor

横から失礼します。 英語をカタカナに変換するもの を作成したので役に立たないかと思います。

cmudictの発音表記もしくは英語のキャラクターいずれがあればカタカナに変換できて、wikitionaryとJMDICT辞書も付属しています。

依頼はnumpyだけで、モデルのweightもpypiのwheelに管理されて、このタスクに便利なので、ちょっと確認いただければと思います。

@sevenc-nanashi
Copy link
Member

Patchethiumさんのc2k(英単語表記->カタカナ)を使うとなるとこんな感じになると思います:

  • 以下の条件を全て満たす場合にc2kを通す:
    • 不明語(フィラー?)
    • 全て小文字、または先頭大文字その他小文字(全大文字とかはだいたい略称なのでアルファベット読みの方が適してそう)
    • 3~5文字以上(ここは要調整、2文字以下は略称として扱って問題ないと思う)
  • アクセントは0型とする(最初のmとかpとかで下がるとかしてもいいけどとりあえず)

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Feb 15, 2025

完全にジャストアイデアなのですが、英単語が連続しているときは単語ごとではなくその英語テキストをg2p-enやc2k等に入力する手も面白いかもですね!
僕も @sevenc-nanashi さんと同じ意見で数文字の英単語はローマ字読みで良い気がしてますが、例えばI am a pen.とかはそうでもないので。

なんて言ってますが、まずはどんな方法でも良いから英単語をそれっぽく読めれば良さそう!
品質上げたり等のこだわりはあとでいくらでもできるので、まずはなるはやでユーザーに届けたい・・・!!

@sevenc-nanashi
Copy link
Member

sevenc-nanashi commented Feb 15, 2025

そういえば:

c2kを埋め込んでみるテストをしました。
https://github.com/sevenc-nanashi/voicevox_engine/tree/poc/e2k

(強引にe2kを入れないと動かない、0.2.0でnumpy1もサポートしたらしいのでアプデしたら動く可能性はある)

また、これと同じ変換条件を自分が管理している読み上げBotで試しています。感想が集まったらここに書きます。

@sevenc-nanashi
Copy link
Member

sevenc-nanashi commented Feb 19, 2025

所感:

  • そこそこまともに動いてくれてそう。
  • 単純な大文字+小文字パターンでは無くPascalCaseみたいなパターンも想定した方が良さそう。
    • これは読み上げBotだからなのでもしかしたらボイボ本体ではいらないかも
      • まぁ想定しておいて損はないはず
  • たまに読みの生成が中途半端になる(EOSが出ちゃってるっぽい)
  • Q&Aあたりに「ちゃんと読ませるなら辞書機能使え」って付け足すと良さそう?

@Patchethium
Copy link
Contributor

Patchethium commented Feb 19, 2025

アイテム2~4の返信:

  • 自分で使ってたのはn-gramで単語っぽいかぽくないかで決める方法。n-gramの得点が高いとg2pに、低いと英字ごとそのまま読む。
  • それ自分もなんとかしたくてbeam searchも試したがあまり差が出なかった。そういえば使ってたモデルは0.1.x?0.2以降は辞書からoutlierを削除したのでちょっとマシになると思う。
  • リリースに辞書があるよ。PyPIに上げていないのはone-to-manyのため。自分で読み込むのもいいし、要望があったら辞書も上げるけど辞書自身も誤りがあるので対処しないといけないかも

@Hiroshiba
Copy link
Member Author

一旦辞書はなしがいいかと思ってます!メンテナンスが大変なので。需要が生まれてからでもいいかなと!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
機能向上 状態:実装者募集 実装者を募集している状態 状態:設計 設計をおこなっている状態
Projects
None yet
Development

No branches or pull requests

5 participants