はじめに
本記事はおしゃべりAIをオフラインかつローカルで実装するシリーズ第三回です。 前回までは、耳となる音声認識、返答を返すtext to textを実装しました。 今回は口となる、合成音声という手法を使ってテキストを音声に変換し(.wavファイル)を生成するプログラムを書きます。
前回
シリーズ
こちらの手順を踏まえて、作っていきたいと思います。 ※ 本シリーズはローカルUbuntuマシンにGPUがある場合を想定しております。
- 第一回:マイクからリアルタイムで音声認識する
- 第二回:音声認識した結果から返答生成する
- 第三回:返答を合成音声で喋らせる ← 今回はこちらになります。
- 第四回:キャラクターが喋っているような見た目を作る
- 第五回:今までで作ったものを組み合わせる
今回の目次
- 合成音声モデルについて
- 合成音声モデルの実装
1. 合成音声モデルについて
概要
合成音声(voice synthesis)モデルはテキストを入力にし、音声を出力する仕組みを指します。 歴史はかなり古くからありますが、機械学習の普及により、より人間らしい声を出力することができるようになってきました。
モデル・サービスの例
text to textモデル同様、音声合成もAzureのテキスト読み上げなどAPI経由で可能なサービスがあります。 今回も、ローカル環境で動作する例でかつ日本語の読み上げに対応している例をご紹介します。
Tacotron2
テキストをメルスペクトログラム(周波数特性を二次元化したもの)へ変換し、そのメルスペクトログラムを音声に変換する2段階のモデルです。
ESPNet
Tacotron2をはじめ、有名な手法をまとめたツールとなります。 Tacotron2に対して処理速度で勝るFastSpeechも実装されています。 最近では、VITSのモデルも追加されました。
VOICEVOX
オープンソースでコマンドで合成音声の出力も可能です。 無料で利用でき、出力可能な声の種類が非常に豊富です。(利用規約が各キャラクターによって異なるためご注意ください)
VOICEPEAK
有料だが、感情(幸せ・楽しみ・怒り・悲しみ)の4パラメータを調節でき、こちらもコマンドラインから合成音声の出力が可能です。(筆者はMacOS・Ubuntuで動作確認できました)
今回は第一回:マイクからリアルタイムで音声認識するでも使用したESPNetを使用していきます。
2. 合成音声モデルの実装
環境構築
第一回:マイクからリアルタイムで音声認識すると同じ環境で実行します。
推論コードの実装
学習済みモデルをmodels/tts
にダウンロードして保存します。
cd models mkdir tts cd tts wget https://zenodo.org/record/5521446/files/tts_finetune_full_band_jsut_vits_raw_phn_jaconv_pyopenjtalk_prosody_latest.zip unzip /tts_finetune_full_band_jsut_vits_raw_phn_jaconv_pyopenjtalk_prosody_latest.zip
モデルの保存が完了後、作業ディレクトリに戻ります。
tools/voice_synthesis.py
import os import soundfile as sf import simpleaudio as sa from espnet2.bin.tts_inference import Text2Speech def load_tts(model_path): fs, lang = 44100, "Japanese" text2speech = Text2Speech( model_file=model_path, device="cuda", speed_control_alpha=1.2, noise_scale=0.333, noise_scale_dur=0.333, ) return text2speech def main(): # Load espnet model_path = "models/tts/exp/tts_finetune_full_band_jsut_vits_raw_phn_jaconv_pyopenjtalk_prosody/100epoch.pth" text2speech = load_tts(model_path) # 読み上げる文章 text = "こんにちは" # 推論 wav = text2speech(text)["wav"] # 音声保存 audio_path = "talk.wav" sf.write(audio_path, wav.data.cpu().numpy(), text2speech.fs, "PCM_16") # 保存した音声を再生 wave_obj = sa.WaveObject.from_wave_file(audio_path) play_obj = wave_obj.play() play_obj.wait_done() if __name__ == '__main__': main()
python tools/voice_synthesis.py
を実行
これで./talk.wav
が作業ディレクトリに保存され、音声が再生されたかと思います!