複数の楽譜・複数の歌手を一度に実行! Google ColaboratoryでNEUTRINOを使うときの便利な方法 (2024/07追記)
背景
NEUTRINOとマシンパワー
NEUTRINO (https://studio-neutrino.com/) は日本語歌唱音声合成ツールの中でも、最近多く使われているものの一つである。非常に高精度な合成音声を作成することができるが、それだけにコンピューターのパワーを要求する。例えばゲーミングPCのように、ハイスペックモデルを持っていれば問題ないが、持っていない人にとってはなかなかに音声合成が完了するまでに時間がかかる。
Google ColaboratoryでのNEUTRINOの実行による解決
そのような問題は、NEUTRINOをGoogle Colaboratoryで利用することで解決できる。Google Colaboratoryでは制限はあるものの、GPUを利用でき、GoogleのコンピューターのパワーでNEUTRINOを軽快に動作させることができる。基本的な実施方法は以下の記事のとおりである。(https://studio-neutrino.com/561/) コンピュータープログラミングをよく知らない人が多いと思われるが、指示通りにファイルをアップロードし、実行すればほぼ困ること無くこの恩恵を受けることができるのでトライする価値はある。
スコアや音声モデルを複数使う
デフォルトでのファイルの課題
しかし、デフォルトで記載されているNEUTRINOのGoogle Colaboratory上での実行ファイル (PythonとBashで記載されている) は、一つのスコアファイルおよび一つの音声モデルを設定し、音声ファイルを出力するように作られている。
楽曲によって状況は異なるとは思うが、合成に時間がかかることを考えると、修正が発生したときのためにスコアファイルは分割して作るのが合理的である。さらに、コーラスが入ればそれだけスコアファイルが増える。通常のワークフローではスコアファイルは複数になることが多い。
また、合成音声であるので複数の音声モデルを重ねて「歌わせる」と、合成特有の違和感が平均化されてきれいに聞こえることがある。このため、音声モデルも同じスコアを複数の音声モデルで利用したいこともある。
こうした状況では一つのスコアファイルおよび一つの音声モデルをいちいち設定するのは結構面倒である。
Bashのループを用いた解決
そこで、Bashを用いて一回の実行で、複数のスコアファイル、複数の音声モデルを一度に作る改造をBashのループを用いて作成した。以下にサンプルコードを記載する。
# Run All process
# Multi-Score and Multi-Model
%%bash
# Project settings
# Model
# "ITAKO" "KIRITAN" "MERROW" "NAKUMO" "SEVEN" "ZUNKO"
MODEL_LIST=("ITAKO" "KIRITAN" "MERROW" "NAKUMO" "SEVEN" "ZUNKO")
# Score
# ("" "" "")
SCORE_LIST=("Vo1" "Vo2" "Vo3")
for model in ${MODEL_LIST[@]}
do
for score in ${SCORE_LIST[@]}
do
BASENAME=$score
NumThreads=0
# NEUTRINO
ModelDir=$model
StyleShift=0
# musicXML_to_label
SUFFIX=musicxml
echo $BASENAME
echo $ModelDir
# WORLD
PitchShift=1.0
FormantShift=1.0
# WORLD(beta version option)
SmoothPitch=0.0
SmoothFormant=0.0
EnhanceBreathiness=0.0
# NSF
GPU_ID=0
# PATH to currennt library
export LD_LIBRARY_PATH=$PWD/bin:$PWD/NSF/bin:$LD_LIBRARY_PATH
echo "`date +"%M:%S.%2N"` : start MusicXMLtoLabel"
./bin/musicXMLtoLabel score/musicxml/${BASENAME}.${SUFFIX} score/label/full/${BASENAME}.lab score/label/mono/${BASENAME}.lab
echo "`date +"%M:%S.%2N"` : start NEUTRINO"
./bin/NEUTRINO score/label/full/${BASENAME}.lab score/label/timing/${BASENAME}.lab ./output/${BASENAME}.f0 ./output/${BASENAME}.mgc ./output/${BASENAME}.bap ./model/${ModelDir}/ -n ${NumThreads} -k ${StyleShift} -t -m
echo "`date +"%M:%S.%2N"` : start WORLD"
./bin/WORLD output/${BASENAME}.f0 output/${BASENAME}.mgc output/${BASENAME}.bap -f ${PitchShift} -m ${FormantShift} -p ${SmoothPitch} -c ${SmoothFormant} -b ${EnhanceBreathiness} -o output/${ModelDir}_${BASENAME}_syn.wav -n ${NumThreads} -t
echo "`date +"%M:%S.%2N"` : start NSF"
./bin/NSF score/label/full/${BASENAME}.lab score/label/timing/${BASENAME}.lab output/${BASENAME}.f0 output/${BASENAME}.mgc output/${BASENAME}.bap ./model/${ModelDir}/model_nsf.bin output/${ModelDir}_${BASENAME}_nsf.wav -g -i ${GPU_ID} -t
echo "`date +"%M:%S.%2N"` : END"
done
done
まず、もともとの実行用ファイルのセクション4の手前にコードを追加し、上記をコピー・アンド・ペーストする。
状況によって、以下の二点を変更する必要がある。
まず、MODEL_LIST=("ITAKO" "KIRITAN" "MERROW" "NAKUMO" "SEVEN" "ZUNKO") の部分を、インストールされていて (Modelフォルダの中にあって) かつそのときに使いたいものだけを残して削除する必要がある。
次に、SCORE_LIST=("Vo1" "Vo2" "Vo3") の部分を、自分で作ったファイル名に差し替える必要がある。
上記変更を終えてから実行すると、すべての音声モデル、すべてのスコアファイルに対して合成音声ファイルが出来上がる。
なお、(実際上問題はないが) bapやf0やmgcと言った拡張子の中間ファイルは順次上書きされてしまうので最後のものに対応したものにしか残らない。
追記 (2023/09)
多くなってくると、SCORE_LISTの部分を書くのが面倒になる。そんなときは上記記述の上に一つコードセルを作って、以下のコードを記述して実行するとSCORE_LISTにコピペ可能な文字列が出てくる。
import glob
files = glob.glob("./score/musicxml/*xml")
names = []
for file in files:
names.append('"' + file.split("/")[-1].replace(".musicxml", "")+ '"')
names.sort
print(" ".join(sorted(names)))
追記 (2024/06)
改良版コードを公開しました。