機械学習
記事内に商品プロモーションを含む場合があります

ESPnet2の使い方|日本語音声合成(Text-To-Speech)編

tadanori

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)については以下の記事で紹介していますので、そちらを参照してください。

あわせて読みたい
ESPnet2の使い方|日本語音声認識 (Speech To Text)編
ESPnet2の使い方|日本語音声認識 (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

エラーが発生しますが、2023.09.02現在の環境では、無視してOKでした

必要なライブラリを読み込む

必要なライブラリを読み込みます。

from espnet_model_zoo.downloader import ModelDownloader
from espnet2.bin.tts_inference import Text2Speech
from espnet2.utils.types import str_or_none
import torch

ModelDownloaderText2Speechがメインとして必要になるライブラリです。

str_or_none()は、文字列が("none", "null", "nil")のいずれかの場合にはNoneを、それ以外の場合には文字列そのものを返す関数です。

torchは、no_grad()を使っているので読み込んでいますが、ここはなくても良い気がします。

読み上げ用のモデルを生成

利用するモデルの設定

tagにモデル名を設定します。

設定できるモデル名はepsnet_model_zooのテーブルで確認することができます。とりあえず、タスクがttsで、日本語の場合はモデル名がjsutjvsのものを選べば良いと思います。今回は、いくつかを聞いてみて、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/”.
https://espnet.github.io/espnet/_gen/espnet2.bin.html?highlight=text2speech#espnet2.bin.tts_inference.Text2Speech

オブジェクトの生成

テキスト読み上げ用のモデルのオブジェクトを生成します。これには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を使うと、音声→文字起こしもできるみたいですので、こちらについてもトライしてみようと思います。

おすすめ書籍

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

記事URLをコピーしました