Top View


Author Han Beomseok

複雑な音声処理タスクを一気通貫で実装できる! ESPnetの概念と特徴について

2021/08/10

TTS(Text To Speech)のプロセス

テキストから人の音声を合成するTTS(Text To Speech)は、「テキスト・音響情報の前処理から、特徴抽出やモデル学習まで」、そのプロセスが複雑で、「言語・音響・統計・機械学習など」様々な基礎知識が必要だと知られています。

ここでは、A Survey on Neural Speech Synthesisを参考にし、TTSプロセスの概念(複雑さ)を理解してもらいたいと思います。

TTSの構成要素

TTSは「テキスト→Lingusitic Feature→Acoustic Feature→Waveform」の変換のため、次の3要素を利用します。

  1. Text Analysis
    テキスト情報を、音声合成しやすい「Linguistic Featureに変換する」プロセスで、次のような処理が行われます。Acoustic Modelの種類によって必要なLinguistic Featureは異なります。

    • Text Normalization
    • Word Segmentation
    • 音素分析 など
  2. 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 など)
  3. 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つの観点から説明したいと思います。

  1. Recipeで管理する音声処理プロセス
  2. 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 ModelPre-trained Vocoderもダウンロードできるので、転移学習・チューニングを通じた、質の良い日本語処理ができるのではないかと思います。

まとめ

今回は、一般的な「TTSプロセス」と「ESPnetでのTTSプロセス」を比較し、「ESPnetのメリット」について詳しく紹介しました。優れたESPnetの再現性のお陰で、Recipeを設定することで、簡単にTTSを実装することができました。

しかし、新たなデータセットを使ったり、Recipeにタスクを追加したりするには、もう少しの工夫が必要だそうです。次は、実際にESPnetのRecipeを構成し、「小さいデータセットでのTTS学習」を実装したいと思いますので、楽しみにして下さい。

Han Beomseok

Han Beomseok

Python, AI Engineering, Natural Language