Table of Contents
TTS(Text To Speech)のプロセス
テキストから人の音声を合成するTTS(Text To Speech)は、「テキスト・音響情報の前処理から、特徴抽出やモデル学習まで」、そのプロセスが複雑で、「言語・音響・統計・機械学習など」様々な基礎知識が必要だと知られています。
ここでは、A Survey on Neural Speech Synthesisを参考にし、TTSプロセスの概念(複雑さ)を理解してもらいたいと思います。
TTSの構成要素
TTSは「テキスト→Lingusitic Feature→Acoustic Feature→Waveform」の変換のため、次の3要素を利用します。
-
Text Analysis
テキスト情報を、音声合成しやすい「Linguistic Featureに変換する」プロセスで、次のような処理が行われます。Acoustic Modelの種類によって必要なLinguistic Featureは異なります。- Text Normalization
- Word Segmentation
- 音素分析 など
-
Acoustic Model
「Linguistic FeatureをAcoustic Featureとマッチさせる」学習モデルで、使用する学習アーキテクチャーによって次のように分けられます。- CNN Based Models(Tacotron Series など)
- RNN Based Models(DeepVoice Series など)
- Transformer Based Models(FastSpeech Series など)
- Other Models(GAN, VAE など)
-
Vocoder
Acousitic Modelから生成したAcoustic Featureを、「実際の音声ファイルに変換する」学習モデルで、Acoustic Modelと同様に様々なモデルが存在します。WORLDのように、公開されたモデルをそのまま使えますが、CNN/GANを用いて新たなVocoderを学習することで、音質を高めることもできます。
要するに、テキストと音声情報から特徴を抽出し、2つの関係を学習することで、テキストから音声情報への変換モデルを構成します。その後、人が聞き取れる音声ファイルに変換することが、TTSの流れになります。
上記の説明からは、TTSプロセスの複雑さが伝わってこないかも知れませんが、TTSの構造をもう少し詳しく見てみましょう。
TTSのデータ流れ
上図は、TTSの構成によるデータ流れを表しています。矢印は「使用できる分析・学習モデル」を、ボックスは「Outputの形式」を意味します。一つのTTSモデルを完成するには、各アルゴリズムの理解はもちろん、言語・音響の分析に関する知識も必要になると思われます。
例えば、本記事の導入部で使った日本語TTSモデルを作るためには、
- データセットダウンロード:学習に十分な量を持ち、スクリプト付きの日本語データセットを探す。
- データ前処理:日本語・自然言語処理に関する知識をベースとして、テキストの正規化・音素分析などを行う。
- 特徴抽出:使用モデルに相応しい形で、データ特徴を抽出する。
- Acoustic Model学習:モデルの構造を理解し、機械学習モデルを構成する。
- Vocoder学習:Pre-trained Vocoderを探したり、必要なら新たなVocoderを学習させたりする。
のようなことを工夫しなければなりません。
この複雑な一連のプロセスは、TTSだけではなく、他の音声処理モデルにおいても同様であり、音声処理研究やモデル実装の大きい壁になっていました。
ESPnetとは?
ESPnetは音声認識(ASR)及び音声合成(TTS)に特化したend-to-en(E2E)音声処理ツールキットで、音声処理モデル研究の加速化のために開発されました。上記のように、音声処理は専門知識のない者として扱いにくい研究分野でしたが、ESPnetのお陰で、誰でも簡単に様々な音声処理を試せるようになりました。
また最初のESPnetは、音声認識E2Eモデルだけを支援していましたが、Open-sourceというメリットを活かせ、今は音声合成(TTS)・機械翻訳(MT)・音声変換(VC)までその機能を拡張しています。
この記事では、ESPnetの特徴を次の2つの観点から説明したいと思います。
- Recipeで管理する音声処理プロセス
- Kaldiスタイルを採用したOpen-sourceツールキット
Recipeで管理する音声処理プロセス
ESPnetは、Recipeというシェルスクリプト構造を用い、複雑な音声処理E2Eプロセスを簡単に実行させています。使用者は、Recipeの一部を修正することで、様々な音声処理タスクを試せます。
Recipeの構造
Recipeとは、一連の音声処理プロセスを複数のタスク(ステージ)で定義したものです。次はESPnetのTTS Recipe構造を表しています。
# TTS Recipe
egs2/jsut/tts1/
- local/
- conf/
- cmd.sh
- path.sh
- db.sh
- tts.sh
- run.sh
tts.shは、TTSに必要な「データダウンロード・前処理・学習・評価」などの複数のステージが定義されたスクリプトであり、run.shの設定に従って実行されます。そして、必要なモジュール・詳細ステージが、他のスクリプトによって管理されています。各スクリプトの詳しい説明は、ESPnetのgithubを参考してください。
このRecipeの作成が「すごく簡単なもの」ではないですが、一般的な音声処理に必要なコードは完成されていて、実際に私は
- local/ : JSUTデータセット用スクリプトコードを追加
- conf/ : TTS学習に使うtacotron2ベースEncode・Decodeコードを追加
- run.sh : 基本的なオプションを設定
を触るだけで、一つのTTSプロセスを構築できました。
(ESPnetでは、データセット構成や学習モデルに関する基本的なコードも提供します。)
Recipeを用いたESPnetのメリット
複雑な音声処理プロセスが簡単に再現できる。
ESPnetには、音声処理に必要な様々なモジュール・ライブラリーが既に用意されていて、簡単に使うことができます。さらに、データセット別・モデル別にRecipe TEMPLATEが細かく作成されているので、ちょっとした手間をかけることで、様々な音声処理プロセスを再現できます。
実際、私が最終的に使ったコードは下のようになります。
./run.sh
--ngpu 1
--lang jp
--g2p pyopenjtalk_accent_with_pause
--train_config conf/tuning/train_tacotron2.yaml
--inference_config conf/tuning/decode_tacotron2.yaml
--inference_model train.loss.best.pth
Recipeのlocalフォルダーには、JSUTデータセットを扱うdata.shスクリプトが作成されているので、このコマンドで
- JSUTデータセットのダウンロード・前処理
- PyOpenJtalkライブラリーを用いた音素分析
- Tacotron2モデルを用いたTTS学習
などが実行され、簡単にTTSプロセスが再現できます。さらに、Tensorboardを用いた学習グラフ・音声特徴の可視化イメージなども自動的に作成してくれるので、音声処理ツールキットとしての活用性は非常に高いと思います。
様々な音声処理プロセスへ拡張できる。
Recipeは複数のステージ(細かいタスク)を組み合わせたもので、ESPnetでは各ステージを統一した形でデザイン・管理しています。従って、作成されたステージを再利用することで、音声処理プロセスが効率よく作成できます。
下の図(参考論文Figure1)は、音声認識(ASR)と音声合成(TTS)Recipeの流れを表していますが、「ステージ-1から2まで」は2つのRecipeで同様に使っていることがわかります。お陰で、ASRの一部ステージをTTSのRecipeに追加することで、無駄な作業を防ぐことができます。
実際に、ESPnetはE2E音声認識モデルのために開発され、今は音声合成・機械翻訳・音声変換までその機能を拡張しています。
また、各ステージを応用し、音声処理タスクを統合することもできると言われています。論文では、Pre-trained ASRモデルを利用し、TTSモデルの評価に使ったり、Semi-supervised TTS学習を行ったりすることもできると述べています。
(ASRは「音声→テキスト」の変換を、TTSは「テキスト→音声」の変換を行います。)
Kaldiスタイルを採用したOpen-sourceツールキット
上の「ASR・TTS Recipeの流れ」図からKaldiという単語が見られますが、ESPnetの特徴としてよく挙げられるものなので、簡単に説明したいと思います。
Kaldiスタイルとは?
Kaldiは、C++ベースで作られたASR向けツールキットで、2009年から行われているプロジェクトです。ESPnetと同様に、Recipe構造を持っていて、扱いやすいASRモデル構築のために開発されたものです。ESPnet Hackathonの動画とESPnetの論文を参考するに、統計モデルをベースとしたHMM基盤のASRモデル(当時のKaldi)を改善するため、Kaldiを参考にして開発したのが、ESPnetの始まりだと思います。
下は、Kaldiで扱うデータ構成を表していますが、ESPnetではこのスタイルを採用しています。
text ## 音声ファイルIDと スクリプト
## BASIC5000_0251 演奏会の切符は、当事務所で販売しています。
spk2utt ## 発話者IDと 音声ファイルID
## JS_1 BASIC5000_0251
## JS_2 BASIC5000_0252
utt2spk ## 音声ファイルIDと 発話者ID
wav.scp ## 音声ファイルIDと PATH
## BASIC5000_0251 downloads/wav/BASIC5000_0251.wav
ESPnetは、Kaldiスタイルを使うので、強大なKaldiのツール・モジュールが使用できます。実際に、初期のESPnet構築にはKaldiのコンパイルが必須であったぐらい、様々なタスクがKaldiに依存していました。
(ESPnet2からは、Kaldiの必要な部分だけをライブラリー化し、Kaldiへの依存性を無くしています。)
Kaldiスタイル・Open-sourceとしてESPnetのメリット
Kaldiの前処理プロセスが利用できる。
上で説明したよう、ESPnetはKaldiスタイルを使い、Kiadiのデータ前処理プロセスを活用しています。データ前処理には多い時間と工夫が必要だと言われていますが、Kaldiスタイルを採用することで、音声処理に必要な様々な前処理への負担を減らしています。
様々な音声処理学習モデルが使える。
ESPnetは、数多い研究者が開発に参加しているOpen-sourceであり、多様な高性能モデルが簡単に使えます。TTS学習に使えるネットワークだけを見てみても、
- Tacotron
- Transfomer-TTS
- FastSpeech など、
様々な学習モデルが既に作成されていて、Recipeのオプションを設定するだけで、モデルの変換ができます。
日々、新たなモデルが研究されている今のところ、最新のモデル・コードが気軽に使えるというのは、Open-sourceとしての一番のメリットであると思います。
また、ESPnet githubのissueでは、インストール・実装上の「エラー解決」はもちろん、音声処理に関する「ディスカッション・Q&A」も盛んに行われているので、ESPnetを使うのなら是非ご覧ください。
日本語向けの多様なモジュールが使える。
ESPnetは渡部晋治さんをリーダーとし、様々な日本の開発者を中心に開発・管理されていて、日本語向けのモジュール・モデルが用意されています。日本語の文書を音素に変換するとき使えるGrapheme to Phonemeモジュール(PyOpenJTalk)や、デキストクリーニングに必要なモジュールなど、日本語処理に有用なオプションが既にセットされています。
それ以外にも、日本語Pre-trained ModelやPre-trained Vocoderもダウンロードできるので、転移学習・チューニングを通じた、質の良い日本語処理ができるのではないかと思います。
まとめ
今回は、一般的な「TTSプロセス」と「ESPnetでのTTSプロセス」を比較し、「ESPnetのメリット」について詳しく紹介しました。優れたESPnetの再現性のお陰で、Recipeを設定することで、簡単にTTSを実装することができました。
しかし、新たなデータセットを使ったり、Recipeにタスクを追加したりするには、もう少しの工夫が必要だそうです。次は、実際にESPnetのRecipeを構成し、「小さいデータセットでのTTS学習」を実装したいと思いますので、楽しみにして下さい。
Han Beomseok
Python, AI Engineering, Natural Language