はじめに
swim-loverです。WaveNet Part(1)の投稿のあと、なるべく早い段階でPart(2)で主に実装・動作確認 をする予定でした。参考としていた先人による実装(https://github.com/r9y9/wavenet_vocoder)を確認していましたが、何分素人なのでなかなか難しい。
ESPnetについての前提知識が必要だと感じました。
そこで WaveNet part(2)の前にESPnetについて触れてみることにしました。
引き続き、ざっくり理解を進めたいと思います。
ESPnetとは
ESPnetは、End to End Speech Processing toolkitと紹介されています。End to Endということなので、このToolkitで音声処理すべてをサポートするということでしょう。
- Deep Learningエンジンとして、pytorchを使用する。
- 実行する処理内容はシェルスクリプトで記述する。これを’レシピ’ という。
- レシピの記述方法は、kaldi styleに従う。
- kaldiも音声認識のオープンソースソフトウェアで、C++にて記述されている。coffe shopのことではない。
とりあえず、参考になるサイトを探して、まずは真似てみることにしました。
音声合成 TTS(Text-to-speech)
音声合成を、1)テキストから音声特徴量(Mel-spectrogram)を出力するブロック、2)音声特徴量から音声を生成するブロック(Vocoder)に分けて処理します。
まず、用語の整理をしてみました。
- スペクトログラム(Spectrogram):音声波形をSTFT(短期間フーリエ変換)したものを二乗したデータ(パワースペクトル)を、横軸:時間、縦軸:パワースペクトルで表したもの。
- メル尺度(Mel slace):数値的に同じ大きさ音声データでも、周波数によって、人の聴覚では音の大きさの感じ方がことなる。人の聴覚に合わせた尺度(scale)をメル尺度という。
- メルスペクトログラム(Mel-spectrogram):スペクトログラムをメル尺度で変換したもの。
ESPnetでは、1)については、次のアーキテクチャをサポートしています。
また、2)については、次のものをサポートしています。
1),2)のいずれも、https://github.com/espnet/espnet に記載の内容になります。
今回は、1)FastSpeech、2)Parallel WaveGANを試してみたいと思います。
ESPnet Install
次のモジュールをインストールします。
- espnet :Espnet本体
- pyopenjtalk:日本語テキスト処理ライブラリ テキストを音素へ変換する
- pypinyin:中国語テキスト処理ライブラリ
- parallel_wavegan:parallel wavegan vocoder
- gdown:google drive 専用ダウンローダー
- espnet_model_zoo:Esp netの学習済モデル
Google Colabより実行します。
!pip install -q espnet==0.10.6 pyopenjtalk==0.2 pypinyin==0.44.0 parallel_wavegan==0.5.4 gdown==4.4.0 espnet_model_zoo
ESPnet Modelの選択
Colab上で、#@titleの表記で タイトル行が表示されます。
#@paramでリストボックスが表示されます。
英語版は、tag=fastspeech,vocoder=parallel_waveganを選択しました。
#@title Choose English model { run: "auto" }
lang = 'English'
tag = 'kan-bayashi/ljspeech_fastspeech' #@param ["kan-bayashi/ljspeech_tacotron2", "kan-bayashi/ljspeech_fastspeech", "kan-bayashi/ljspeech_fastspeech2", "kan-bayashi/ljspeech_conformer_fastspeech2", "kan-bayashi/ljspeech_joint_finetune_conformer_fastspeech2_hifigan", "kan-bayashi/ljspeech_joint_train_conformer_fastspeech2_hifigan", "kan-bayashi/ljspeech_vits"] {type:"string"}
vocoder_tag = "parallel_wavegan/ljspeech_parallel_wavegan.v1" #@param ["none", "parallel_wavegan/ljspeech_parallel_wavegan.v1", "parallel_wavegan/ljspeech_full_band_melgan.v2", "parallel_wavegan/ljspeech_multi_band_melgan.v2", "parallel_wavegan/ljspeech_hifigan.v1", "parallel_wavegan/ljspeech_style_melgan.v1"] {type:"string"}
ESPnet Model Setup
日本語版も準備しておきます。
#@title Choose Japanese model { run: "auto" }
lang = 'Japanese'
tag = 'kan-bayashi/jsut_fastspeech' #@param ["kan-bayashi/jsut_tacotron2", "kan-bayashi/jsut_transformer", "kan-bayashi/jsut_fastspeech", "kan-bayashi/jsut_fastspeech2", "kan-bayashi/jsut_conformer_fastspeech2", "kan-bayashi/jsut_conformer_fastspeech2_accent", "kan-bayashi/jsut_conformer_fastspeech2_accent_with_pause", "kan-bayashi/jsut_vits_accent_with_pause", "kan-bayashi/jsut_full_band_vits_accent_with_pause", "kan-bayashi/jsut_tacotron2_prosody", "kan-bayashi/jsut_transformer_prosody", "kan-bayashi/jsut_conformer_fastspeech2_tacotron2_prosody", "kan-bayashi/jsut_vits_prosody", "kan-bayashi/jsut_full_band_vits_prosody", "kan-bayashi/jvs_jvs010_vits_prosody", "kan-bayashi/tsukuyomi_full_band_vits_prosody"] {type:"string"}
vocoder_tag = 'parallel_wavegan/jsut_parallel_wavegan.v1' #@param ["none", "parallel_wavegan/jsut_parallel_wavegan.v1", "parallel_wavegan/jsut_multi_band_melgan.v2", "parallel_wavegan/jsut_style_melgan.v1", "parallel_wavegan/jsut_hifigan.v1"] {type:"string"}
Colab GPU有効化
ColabのGPUを有効化しておきます。
ESPnet Model setup
音声合成のセットアップを行います。
#@title Model Setup
from espnet2.bin.tts_inference import Text2Speech
from espnet2.utils.types import str_or_none
text2speech = Text2Speech.from_pretrained(
model_tag=str_or_none(tag),
vocoder_tag=str_or_none(vocoder_tag),
device="cuda",
# Only for Tacotron 2 & Transformer
threshold=0.5,
# Only for Tacotron 2
minlenratio=0.0,
maxlenratio=10.0,
use_att_constraint=False,
backward_window=1,
forward_window=3,
# Only for FastSpeech & FastSpeech2 & VITS
speed_control_alpha=1.0,
# Only for VITS
noise_scale=0.333,
noise_scale_dur=0.333,
)
ESPnet Synthesis
音声合成を実行します。
#@title Synthesis
import time
import torch
# decide the input sentence by yourself
print(f"Input your favorite sentence in {lang}.")
x = input()
# synthesis
with torch.no_grad():
start = time.time()
wav = text2speech(x)["wav"]
rtf = (time.time() - start) / (len(wav) / text2speech.fs)
print(f"RTF = {rtf:5f}")
# let us listen to generated samples
from IPython.display import display, Audio
display(Audio(wav.view(-1).cpu().numpy(), rate=text2speech.fs))
実行すると、テキストの入力ボックスが現れるので、好きな日本語を入力します。
再生ボタンを押すことで音声合成の結果(wav)ファイルを聞くことができます。
海へのところがやや不自然な印象ですが、音声合成は成功しました。
まとめ
今回は、End to Endの音声処理キットであるESPnetについて取り上げました。ModelはFastSpeech、Vocoderは、Parallel WaveGANを使用しました。
組み込み系ソフトエンジニアをしています。これまでフロントエンド技術は避けてきましたが、食わず嫌いをやめて、勉強を始めました。
趣味は、水泳、ロードバイク、ランニング、登山です。
組み込み系技術ネタ、勉強したフロントエンド技術、たまに趣味の運動について発信していきます。
どうぞよろしくお願いします。
コメント