ESPnet2を使った日本語音声合成(Text-To-Speech)の手順解説
本記事では、ESPnet2を使った日本語のText-To-Speech(TTS)音声合成について解説します。ESPnet2は、PyTorchをベースにした高機能なツールで、テキストから音声への変換を行うことが可能です。この記事では、ESPnet2のインストール手順から、実際の使い方まで詳しく解説します。
PythonでText-To-Speech(Text2Speech)
pytorchでText-To-Speech(音声合成、テキスト読み上げ)をやりたいと思いネットで調べてみました。調べてみるとESPnet2というものを使えば簡単に行うことができるようでしたので、実際に使ってみました。この記事では、ESPnet2を使った音声合成の手順を解説します。
参考リンク:ESPnet2のリポジトリ
ESPnet2について
ESPnet2は、End-to-End(エンドツーエンド)の音声認識、テキスト読み上げ、音声翻訳、音声言語理解などをカバーするツールキットEPSnetの第2世代版です。
End-to-Endのアーキテクチャを採用しているので、音声処理の各ステップ(特徴抽出、言語モデル、音響モデル)などの処理を個別に扱うのではなく、入力から出力までの処理を1つのネットワークで処理することができます。
これにより、モデルの構築・学習・デプロイなどが簡単化されています。
説明したようにEPSnet2はさまざまなタスクで利用できますが、ここではEPSnet2をテキスト読み上げに利用してみます。
テキスト読み上げは、タスクとしては、Text-To-Speech(TTS)に分類されるので、EPSnet2のドキュメントを調べる場合には、TTSタスクで検索してみてください。
なお、音声認識(Speech-to-Text)については以下の記事で紹介していますので、そちらを参照してください。
コードについて
今回のコードは、Google Colab用のコードとしてGithubに置いています。
Google Colab用コード:Text-to-Speechのサンプルコード(Github)
※GPUを利用するコードになっていますので注意してください
ライブラリのインストール
必要なライブラリをColab環境にインストールします。
ライブラリのインストールのコードは以下になります。Colab環境以外の場合は、先頭の!
を除いてコマンドラインで実行してインストールしてください。
!pip install -q espnet pypinyin parallel_wavegan gdown espnet_model_zoo
!pip install -q --no-build-isolation pyopenjtalk
必要なライブラリを読み込む
必要なライブラリを読み込みます。
from espnet_model_zoo.downloader import ModelDownloader
from espnet2.bin.tts_inference import Text2Speech
from espnet2.utils.types import str_or_none
import torch
ModelDownloader
とText2Speech
がメインとして必要になるライブラリです。
str_or_none()
は、文字列が("none", "null", "nil")
のいずれかの場合にはNoneを、それ以外の場合には文字列そのものを返す関数です。
torchは、no_grad()を使っているので読み込んでいますが、ここはなくても良い気がします。
読み上げ用のモデルを生成
利用するモデルの設定
tag
にモデル名を設定します。
設定できるモデル名はepsnet_model_zooのテーブルで確認することができます。とりあえず、タスクがtts
で、日本語の場合はモデル名がjsut
かjvs
のものを選べば良いと思います。今回は、いくつかを聞いてみて、kan-bayashi/jsut_full_band_vits_prosody
を選択しています。vocoder_tag
はとりあえずnone
を設定しています。
# モデル名などの設定(https://github.com/espnet/espnet_model_zoo/blob/master/espnet_model_zoo/table.csv からjvs, justを選択)
tag = 'kan-bayashi/jsut_full_band_vits_prosody'
vocoder_tag = 'none'
vocoder_tagを設定しているttsが見つからなかったので、とりあえずnone設定しています。ドキュメントには、以下のように書かれていて、parallel_wavegan/で始まるものを設定するようです。
- vocoder_tag (Optional[str]) – Vocoder tag of the pretrained vocoders. Currently, the tags of parallel_wavegan are supported, which should start with the prefix “parallel_wavegan/”.
オブジェクトの生成
テキスト読み上げ用のモデルのオブジェクトを生成します。これにはText2Speech
を使います。なお、from_pretrained()
でオブジェクトを生成することで学習済みのモデルを読み込むことが可能です。
text2speech = Text2Speech.from_pretrained(
model_tag=str_or_none(tag),
vocoder_tag=str_or_none(vocoder_tag),
device="cuda",
)
これを実行すると、text2speech
のオブジェクトが生成されます
テキスト読み上げ
テキスト→音声変換
テキスト読み上げは非常に簡単です。
text
に読み上げたい文字列をセットして、text2speech()
に入力します。
結果は辞書型で戻ってくるので、音声データ(wav
)だけ取り出します。
最後に、wavのサイズをサンプリングレート(text2speech.fs
)で割って秒数を計算しています。
text = "吾輩は猫である。名前はまだ無い。 どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。"
with torch.no_grad():
wav = text2speech(text)["wav"]
print(wav.shape[0]/text2speech.fs, "sec." )
Colabで再生
Colabで音声の再生ボタンを埋め込むには、IPythonパッケージを利用します。
具体的なコードは以下になります。
# 再生用のボタンを埋め込む
from IPython.display import display, Audio
display(Audio(wav.view(-1).cpu().numpy(), rate=text2speech.fs))
これを実行すると以下のようなボタンが表示されます。これをクリックすると音声が再生します
ちなみに、生成した音声は以下になります。意外と自然な発話だと感じますがどうでしょうか。
wavファイルに保存
ついでに、wavファイルでの保存もやってみます。今回はtorchaudio
を利用しました。以下のコードで音声をファイルに保存できます(ここでは、test.wav
に保存しています)
# wavデータとして保存する
import torchaudio
y = wav.reshape(1, len(wav)).cpu()
rate = text2speech.fs
torchaudio.save(filepath="test.wav", src=y, sample_rate=rate)
display(Audio("test.wav"))
終わりに
いかがでしたか? テキスト読み上げも結構簡単にできると感じたのではないでしょうか。ESPnet2を使うと、音声→文字起こしもできるみたいですので、こちらについてもトライしてみようと思います。