Merlinで話者依存モデル。深層学習でリアルな合成音声を作る! 英語デモ編

Ubuntu18.04で、HTSの後継である合成音声ライブラリMerlinを使って音声合成をしてみたいと思います。ディープニューラルネットワーク(DNN)を使っているため、従来のHTSによる生成声よりもクオリティが断然アップするはずです!まずは英語のデモからやってみて、感覚をつかみたいと思います。
こちらを主に参考にさせていただきました。

1.準備

①Merlinのインストール

~$ git clone https://github.com/CSTR-Edinburgh/merlin.git
~$ cd merlin/tools
~/merlin/tools$ ./compile_tools.sh

②早速のエラー:「cmakeがないよ」

コンパイルのときに使用している”cmake”が入っていないせいで、”bin/REAPER”の中身が空になっていました。なのでcmakeをインストールします。

~$ sudo apt install cmake

上記でうまくいかない場合は、直接ダウンロードします。

~$ wget https://cmake.org/files/v3.4/cmake-3.4.0-rc3.tar.gz
~$ tar xvf cmake-3.4.0-rc3.tar.gz
~$ cd cmake-3.4.0-rc3/
~$ ./configure
~$ make
~$ sudo make install
~$ export PATH="/usr/local/bin:$PATH"
~$ cmake

もう一度以下を実行すれば、無事にインストールできます。

~/merlin/tools$ ./compile_tools.sh

③pipによる諸々のインストール

~/merlin$ pip install numpy scipy matplotlib lxml theano bandmat

  

2.デモの実行(英語音声です)

①一番シンプルなデモ

以下を実行すると、”merlin/egs/slt_arctic/s1/slt_arctic_demo_data”の中にあるサンプルデータ(50個)でデモが実行されます。

~/merlin$ cd egs/slt_arctic/s1/
~/merlin/egs/slt_arctic/s1$ ./run_demo.sh

実行後、生成されるwavファイルは”merlin/egs/slt_arctic/s1/experiments/slt_arctic_demo/test_synthesis/wav”の中にあります。

②GPUを使いたい

run_demo.shを実行した時のログを見てみると、GPU関連のところで、「pygpuがimportできないよ」というエラーが出ており、CPUを使って実行していました。これでは大規模な計算になるとダウン必至です。pygpuは”conda”を使ったインストールが基本のようですが、余計なものを入れたくなかったので、こちらを参考に別の方法で入れました。

~$ git clone https://github.com/Theano/libgpuarray.git
~$ cd libgpuarray
~/libgpuarray$ mkdir build
~/libgpuarray$ cd build
~/libgpuarray/build$ cmake .. -DCMAKE_BUILD_TYPE=Release
~/libgpuarray/build$ make
~/libgpuarray/build$ sudo make install
~/libgpuarray/build$ cd ..
~/libgpuarray$ python3 setup.py build
~/libgpuarray$ python3 setup.py install

ちなみに自分の場合Virtualenv内でやろうとしたのですが、どうあがいてもpygpuがVirtualenv内に保存されてくれなかったので、/usr/local/lib/python3.6/dist-packages/pygpu-0.7.6+20.g9cec614-py3.6-linux-x86_64.egg内のpygpuと/home/ユーザー名/.local/lib/python3.6/site-packages内にあるmakoとmarkupsafeの3つのディレクトリをVirtualenv内のlib/python3.6/sitepackagesの中に手動で移動させました…

さらに、GPU駆動のためにはCudaとCudnnのバージョンが一致している必要があります。Cuda-8.0がMerlinとともに自動で入るのですが、Cudnnは別途インストールする必要があるので注意が必要です。自分の場合、以前Cuda-9.1を入れていたので、こちらを使うために、merlin/src/setup_env.shの13行目のcudaに関するパスをcuda-9.1に変更しました。参考リンクはこちら

③GPUを使って実行!

GPUを使ってもう一度実行してみます。ところが、ログの中に

WARNING (theano.tensor.blas): Using NumPy C-API based implementation for BLAS functions.

という警告が。調べてみると、BLAS(Basic Linear Algebra Subprograms)というものを入れないとnumpyの本来の実力を発揮できない模様です。以下のコマンドでOpenBLASを入れて、numpyをaptで再インストールしました。(こちらを参考に)

~$ sudo apt install -y libopenblas-base libopenblas-dev
~$ sudo apt install python3-numpy

すると、エラーなくGPUで実行できました!
念の為CPUとGPUでかかる時間を(アナログに)計測してみると、
CPU:2分17秒 GPU:50秒
ということで、しっかりと差が出ていました。感動。

④本格的なデモ

run_demo.shではなく、run_full_voice.shを実行すると、1132個のデータで実行され、本格的な生成声が得られます。GPU使うと結構早く終わってびっくりしました(10分ほど)。

~/merlin$ cd egs/slt_arctic/s1/
~/merlin/egs/slt_arctic/s1$ ./run_full_voice.sh

実行後、生成されるwavファイルは”merlin/egs/slt_arctic/s1/experiments/slt_arctic_full/test_synthesis/wav”の中にあります。生成声、めちゃ高音質です。

⑤新規テキストの読み上げ

merlin_synthesis.shを使うと、自分のつくったテキストファイルを音声に変換できます。run_demo.shをやった直後なら~/merlin/egs/slt_arctic/s1/experiments/slt_arctic_demo/test_synthesisのところにtxtディレクトリを作成し、その中に自作テキストファイル.txtを格納します。
run_full_voice.shをやった直後なら~/merlin/egs/slt_arctic/s1/experiments/slt_arctic_full/test_synthesisのところにtxtディレクトリを作成し、その中に自作テキストファイル.txtを格納します。

そのまま実行すると「festivalにパスが通っていません」と怒られるので、festivalをダウンロードし、~/merlin/toolsの中に入れます。

そうすると、無事に実行されると思います。生成には意外と時間かかりますね。自分の環境だと7秒くらいかかりました。生成されたwavファイルは、~/merlin/egs/slt_arctic/s1/experiments/slt_arctic_demo/test_synthesis/wavまたは~/merlin/egs/slt_arctic/s1/experiments/slt_arctic_full/test_synthesis/wavの中に、テキストファイルと同じ名前であります。

  

これで、準備およびデモ実行は完了です。次回は日本語の音声での実行をしてみたいと思います。

10件の返信

  1. 阿部高志 より:

    やっとmerlinのところまでたどり着きました。
    (まだ、前回の話者適応でのすべてができたわけではないですが……)
    一応merlinを使いこのページの最後まで行うこと自体はできましたが、いろいろとエラーなどが発生し、フルサンプルデモもすべてを音声ファイルにすることができず、新規テキストはlabファイルが空になってしまい音声ファイルが作成できなかったので報告します。

    今回もvirtualboxでubuntuを使いました。
    なので、updateやupgradeをしないとpipコマンドのインストールができなかったり、gitをインストールしないとそもそもmerlinのクローンを作れませんでした。
    pipでのインストール前にもrealpathやautotools-devなどのインストールや、c++のコンパイルができないので
    $ sudo apt install build-essential
    再び、このコマンドを使いました。
    pipでのインストールも一つずつしないとエラーが起きてしまいましたね。

    今回は結果だけを急いでいたのでGPUを後回しにしてCPUでの処理を行いました。
    それがフルサンプルデモが全て処理できなかった原因かもしれません。
    エラーは以下です。
    MemoryError
    500ファイル程度まで実行されているので、恐らくそのあたりで何かしらの処理の限界が来たのではないかと思います。

    新規テキストの件は

    Traceback (most recent call last):
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 1320, in
    main_function(cfg)
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 971, in main_function
    generator.acoustic_decomposition(gen_file_list, cfg.cmp_dim, cfg.out_dimension_dict, cfg.file_extension_dict, var_file_dict, do_MLPG=cfg.do_MLPG, cfg=cfg)
    File “/home/ユーザー名/merlin/src/frontend/parameter_generation.py”, line 164, in acoustic_decomposition
    gen_features = mlpg_algo.generation(current_features, var, out_dimension_dict[feature_name]//3)
    File “/home/ユーザー名/merlin/src/frontend/mlpg_fast.py”, line 122, in generation
    var_frames[0, 1] = 100000000000;
    IndexError: index 0 is out of bounds for axis 0 with size 0
    deleting intermediate synthesis files…
    synthesized audio files are in: experiments/slt_arctic_demo/test_synthesis/wav

    このようにあり、wavにオーディオファイルが作成されているとありますが、作成されていません。
    内部を検索してlabファイルを見たところ空だったので、文字をラベル処理? できていなかったのが判明しています。
    前回のようにpythonファイルの何かしらの変更をしないといけないのでしょうか?
    それともtxtファイルの書き方などがあるのでしょうか?(中身は英文章にして、一行分程度です)

  2. 阿部高志 より:

    >MemoryError
    >500ファイル程度まで実行されているので、恐らくそのあたりで何かしらの処理の限界が来たのではないかと思います。

    ここの部分は勘違いでした。
    開くディレクトリの階層を間違えていました。

    エラーはCPUを増やしてみたところ
    ./s1/scripts/submit.sh
    の48行目で強制終了するようになりました。
    ファイル内を調べてみても「fi」で終わっているため何のことかさっぱりです。

    やはりGPUを使わないといけないということでしょうか?

    • kyabe2 より:

      Merlinに挑戦ですか!
      MemoryErrorは解決したようで良かったです。実行しているrun_demo.shですが、中身を見ると01_setup.shから05_run_merlin.shを順番に、引数を入れながら実行しているだけですので、一つ一つ実行してみていただいてもいいですか?そして、01から05のどこでどんなエラーが発生しているか詳しく教えていただいてもよろしいでしょうか?

  3. 阿部高志 より:

    一度環境を作り直してみたところ余計にこんがらがってしまいました。

    日本語をもう一度試したところエラーが起きたので、本家のやり方を見ながら一つずつ試しました。
    すると、STEP6でエラーが起きました。

    2020-01-31 17:32:30,130 INFO acoustic_comp: processing file 6 of 50 : /home/ユーザー名/merlin/egs/japanese_voice/s1/experiments/japanese_voice/acoustic_model/inter_module/nn_mgc_lf0_vuv_bap_199/a06.cmp
    Traceback (most recent call last):
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 1320, in
    main_function(cfg)
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 692, in main_function
    perform_acoustic_composition(delta_win, acc_win, in_file_list_dict, nn_cmp_file_list, cfg, parallel=True)
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 510, in perform_acoustic_composition
    pool.map(perform_acoustic_composition_on_split, splits_full)
    File “/usr/lib/python2.7/multiprocessing/pool.py”, line 253, in map
    return self.map_async(func, iterable, chunksize).get()
    File “/usr/lib/python2.7/multiprocessing/pool.py”, line 572, in get
    raise self._value
    IOError: [Errno 2] No such file or directory: ‘/home/ユーザー名/merlin/egs/japanese_voice/s1/experiments/japanese_voice/acoustic_model/data/mgc/a06.mgc’

    用意したファイルは50個、読み上げ用は5個なっています。

    相変わらずサンプルの50個は成功するのですがフルと新規テキストがエラー、日本語もエラーが起きてしまうので、このあたりのSTEPが問題なんですよね。
    最初は読み上げ用が5個なので6個目は無くてエラーなのかと思いましたが

    2020-01-31 17:47:16,477 INFO dnn_generation: generating 1 of 5: /home/ユーザー名/merlin/egs/japanese_voice/s1/experiments/japanese_voice/test_synthesis/wav/a01.lab
    Traceback (most recent call last):
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 1320, in
    main_function(cfg)
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 945, in main_function
    dnn_generation(test_x_file_list, nnets_file_name, lab_dim, cfg.cmp_dim, gen_file_list, reshape_io)
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 437, in dnn_generation
    predicted_parameter = dnn_model.parameter_prediction(test_set_x)
    File “/home/ユーザー名/merlin/src/models/deep_rnn.py”, line 279, in parameter_prediction
    predict_parameter = test_out()
    File “/home/ユーザー名/.local/lib/python2.7/site-packages/theano/compile/function_module.py”, line 917, in __call__
    storage_map=getattr(self.fn, ‘storage_map’, None))
    File “/home/ユーザー名/.local/lib/python2.7/site-packages/theano/gof/link.py”, line 325, in raise_with_op
    reraise(exc_type, exc_value, exc_trace)
    File “/home/ユーザー名/.local/lib/python2.7/site-packages/theano/compile/function_module.py”, line 903, in __call__
    self.fn() if output_subset is None else\
    File “/home/ユーザー名/.local/lib/python2.7/site-packages/theano/gof/op.py”, line 892, in rval
    r = p(n, [x[0] for x in i], o)
    File “/home/ユーザー名/.local/lib/python2.7/site-packages/theano/tensor/blas.py”, line 1552, in perform
    z[0] = np.asarray(np.dot(x, y))
    ValueError: (‘shapes (918,675) and (671,1024) not aligned: 675 (dim 1) != 671 (dim 0)’, (918, 675), (671, 1024))
    Apply node that caused the error: Dot22(, W)
    Toposort index: 7
    Inputs types: [TensorType(float32, matrix), TensorType(float32, matrix)]
    Inputs shapes: [(918, 675), (671, 1024)]
    Inputs strides: [(2700, 4), (4096, 4)]
    Inputs values: [‘not shown’, ‘not shown’]
    Outputs clients: [[Elemwise{Composite{tanh((i0 + i1))}}[(0, 0)](Dot22.0, InplaceDimShuffle{x,0}.0)]]

    Backtrace when the node is created(use Theano flag traceback.limit=N to make it longer):
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 1320, in
    main_function(cfg)
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 870, in main_function
    cmp_mean_vector = cmp_mean_vector, cmp_std_vector = cmp_std_vector,init_dnn_model_file=cfg.start_from_trained_model)
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 247, in train_DNN
    dropout_rate = dropout_rate, optimizer = cfg.optimizer, rnn_batch_training = cfg.rnn_batch_training)
    File “/home/ユーザー名/merlin/src/models/deep_rnn.py”, line 93, in __init__
    hidden_layer = GeneralLayer(rng, layer_input, input_size, hidden_layer_size[i], activation=hidden_activation, p=self.dropout_rate, training=self.is_train)
    File “/home/ユーザー名/merlin/src/layers/layers.py”, line 224, in __init__
    self.output = T.dot(self.x, self.W) + self.b

    HINT: Use the Theano flag ‘exception_verbosity=high’ for a debugprint and storage map footprint of this apply node.

    STEP7でこのようなエラーが出てしまい途中でエラーが発生しているのだと気づきました。

    日本語ページではないですが、前回は500で一回失敗して50個に減らしているので、50個分成功してエラーが発生せずというパターンだったのかもしれません。
    ストレージの関係上環境を一度削除してしまったので確認できませんが…。
    一つずつ試すというのも本家サイトを見た限りではどのファイルやパスを指定するのかもわからずじまいで。

    また、festivalは話者適応で質問した2.5系のものでかまわないのでしょうか?
    festivalの中のbinの中にfestivalがないとエラーが出たりするもので…。

    長々と申し訳ないですがよろしくお願いします。

    • kyabe2 より:

      まず、festivalに関しては、2.5でもいけるはずです。ただ、参照するディレクトリが~merlin/toolsになっているので、そこにfestivalフォルダ単体(speech_toolsと一緒のやつではないということ)を移動していただければと思います。

      次に本題ですが、エラーに関して03_prepare_acoustic_features.shの段階でエラーが出てはいないでしょうか?そしてログの中に「The file is not .wav format.」という文言が入っていたり…?
      もしその場合、このページ(https://github.com/CSTR-Edinburgh/merlin/issues/274)によるとすべてのwavファイルのメタデータを削除するとうまく行くみたいで、STEP3のエラーがなくなれば、STEP6以降のエラーがなくなったりしないでしょうか?
      完全なエラーの再現ができないので、憶測ですみません…汗

  4. 阿部高志 より:

    新規テキストができない原因がわかりました。

    まず、festivalは話者適応のときと同じくバージョン系がありました。
    2.5系と「festvox_…」で始まる5つのファイル「festvox_…」で始まる5つのファイルを一つにまとめる作業を行いました。
    さらに、その時と同じエラーが発生したので
    $ sudo apt install libncurses5-dev libncursesw5-dev
    入れるだけではダメなようで、
    $ ./configure
    $ make
    $ make install
    話者適応と同じやり方で進めていきました。
    すると、エラーが起きず
    deleting intermediate synthesis files…
    synthesized audio files are in: experiments/slt_arctic_demo/test_synthesis/wav
    無事サンプルの音声ファイルがあるwavフォルダに用意したtxtと同じ名前の音声ファイルができていました。

    残すはフルサンプルと日本語を再度できるようになることです!

    • kyabe2 より:

      返信遅くなりました。
      festival関係が解決した模様で、よかったです!
      日本語の方、自分の環境でも再度やろうとしているのですが、自分もエラーに見舞われ中です…
      merlinまだまだ分からないことだらけですみません汗

  5. 阿部高志 より:

    お久しぶりです。
    現在はmerlinの中身を勉強したりして、フルコンテキストの作り方や内容の意味、音響モデルがどのように学習されているのか勉強して過ごしています。

    ①その中で何度かエラーが起きてしまうことがあったのでお聞きしたいです。
    新規作成を行うため根井準備を整え、merlin_synthesis.shを実行した後です。

    Traceback (most recent call last):
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 1320, in
    main_function(cfg)
    File “/home/ユーザー名/merlin/src/run_merlin.py”, line 971, in main_function
    generator.acoustic_decomposition(gen_file_list, cfg.cmp_dim, cfg.out_dimension_dict, cfg.file_extension_dict, var_file_dict, do_MLPG=cfg.do_MLPG, cfg=cfg)
    File “/home/ユーザー名/merlin/src/frontend/parameter_generation.py”, line 164, in acoustic_decomposition
    gen_features = mlpg_algo.generation(current_features, var, out_dimension_dict[feature_name]//3)
    File “/home/ユーザー名/merlin/src/frontend/mlpg_fast.py”, line 122, in generation
    var_frames[0, 1] = 100000000000;
    IndexError: index 0 is out of bounds for axis 0 with size 0
    deleting intermediate synthesis files…
    synthesized audio files are in: experiments/slt_arctic_demo/test_synthesis/wav

    merlinの英語版サンプルデモ(50)で行い、新規作成を行った際に起きました。
    HTSでも二度目以降を行おうとしたときなど発生したことがあり、再度環境を構築しなおしたりして対処しています。

    IndexError: index 0 is out of bounds for axis 0 with size 0

    調べても上記の部分がよくわからず、インデックスに何かあるのかと思いましたが知識不足で意味不明でした。
    起きるときと起きないとき、起きれば作り直さないといけないので原因は分からないでしょうか?
    フルコンテキストは作成されていますので、作成されていないのはwavの中に作られるはずの音声ファイルだけです。

    ②また、フルコンテキストについてもお聞きしたいです。
    monophoneはアクセントや声の抑揚情報がない平坦でしゃべらせるだけのもの、と考えてよろしいですか?
    フルコンテキストの中身はopen-jtalkのログを取り出したもので、monophoneに時間と音素以外のデータが付与された情報。
    音素以降のxxがたくさんあるデータの意味が分かりません。
    open-jtalkを使うのが簡単らしいのですが、何なのかを理解できた方がいいと思ったので質問させていただきます。

    ③最後に、音響モデルなどの中身を見ることはできないでしょうか?
    merlinの学習はstepごとのファイルを見て少しずつ把握してきたのですが、一体どのような学習をしているのかわからずrun_merlin.pyの調査で停滞しています。
    とりあえず、呼び出しが起きる関数から実行されているのはなんとなくわかるのですが……。

    難しい質問かと思いますが、よろしくお願いします。

    • kyabe2 より:

      お久しぶりです。その熱心な姿勢に感化されます!
      最近合成音声にはご無沙汰してしまっているので、もしかすると質問者さんの方がお詳しくなりつつあるかもです…汗
      まずお答えできそうな②の質問ですが、おっしゃるようにmonoラベルは前後の文脈の情報を持たないただの「音」の情報で、fullラベルは前後の音の情報も加味した「音の流れ」の情報、という感じで自分も理解しています。中身の詳細に関してはこの記事(https://gist.github.com/yamachu/5dab4393ade50173bebe51c65cd9e8f3)がとても参考になります!
      ①に関しては、似たようなエラーにあっている方がここ(https://github.com/CSTR-Edinburgh/merlin/issues/352)で質問されているみたいです。これによるとfestivalが.uttから.labを作る過程で何か問題が起きていて、空の.labファイルができてしまっているのが怪しいと言っているようです。slt_arctic_demoの中にある「gen-lab」と「prompt-lab」の中のファイルは無事にできていらっしゃいますでしょうか?
      ③に関しては、まだ自分も完全には理解できておりません…。このページ(http://jrmeyer.github.io/tts/2017/02/14/Installing-Merlin.html)で結構詳しく解説してくれてはいますが、英語なのでなかなか骨が折れますね。ただおそらく音響モデルのファイル群はバイナリ形式のものが多く、コンピュータにとってしか理解できない形である可能性が高いです。
      また何か新しいことが分かれば、追って共有させていただきます!

  6. 阿部高志 より:

    IndexError: index 0 is out of bounds for axis 0 with size 0

    このエラーの件、解決しました!
    指摘された通り「gen-lab」と「prompt-lab」の中のファイルを確認したところ、一つのファイルが空となっていました。
    そこからどう直せばいいのか悩み、用意したtxtファイルをのぞいていたところ文章の最後に「!」が付いていることに気づき、消して試してみると成功した感じです。

    原因が「!」なのか定かではありませんが、無事成功してよかったです。
    お騒がせしました。
    (サンプル実行時に起きる場合があるので若干謎が残りますが)

    ②、③についても回答ありがとうございます。
    やはりこつこつ解明していくほかないようですね。
    学習方法の流れがわかれば一気に進みそうな気がしたのですが。(それでも難しすぎる気はしますね)

    こちらも何かわかれば共有させていただきたいと思っています。

コメントは受け付けていません。