まえがき
Twitterではいつも成果報告のみに留めていたこういった技術情報ですが、今となってはTumblr支部 YKRV.NETにブログシステムが導入が出来たことで書き放題ですね。ついに私も技術者向け記事を仕上げることになるとは…という事で最初の記念すべき題材はタイトル通りです。
最近話題の機械学習ですが、私はどちらかというと学習そのものの工程やTraining Operationに対して興味があるのでよくこういった事には手をつけていましたが、その中で役に立ちそうな情報が仕上がったので載せておきます。
さて、こちらのMMVCについての説明は省いて
「Colab上で学習環境を構築したのは良いものの、課金してまでわざわざColab上でやらなくてもそれなりのGPUを持っているからローカル上で学習させたい!」
という方向けの実際にこちらで試して成功した移行手順をメモ代わりに書いておきます。
※ローカル環境構築そのものの手順については既に開発者様のリポジトリに「ローカル環境構築」ドキュメントがありますが、そのままの手順でやっても詰まる箇所があったのでそれを補う内容・こちらで独自に解決策を調査したものを掲載します。
STEP1
Googleドライブ上にて「MMVC_Trainer-main」フォルダをダウンロードする。
既に1度学習を走らせた場合、フォルダのDLをすると勝手にGoogle側で分割されたzipとして渡してくると思われるのでその場合はDL後に自主的にマージするのをお忘れずに。
STEP2
ドキュメント「1. WSL2にUbuntu20.04を作成し、最新にする」を実行。
#Ubuntu環境が既にある場合は削除する
と書かれていますが、導入の仕方を工夫すれば複数環境を独立させて使い分けられる機能(tarとしてexportした後にimport等)がWSL上にあるのでやっておくと良いでしょう。ドライブもCから移行出来るのでSSD等の消耗を気にするなら尚更。
#WSL2 Ubuntuを再起動する
wsl -t Ubuntu-20.04
以降の手順でも再起動の指示がありますが、個人的には cmdで
wsl.exe ––shutdown
の方法での再起動を勧めておきます。
※このコマンドで再起動しないとOS起動時のログが出て来ないようなので"wsl -t"での再起動はしっかり再起動できているか怪しいかも
STEP3
ドキュメント「2. MMVC_Trainerのデータを配置する」を実行。
特にこだわりがないなら「/home/hogehoge/MMVC_Trainer-main」に配置すればいい。
Windows側からアクセスする際のパス例
\wsl.localhost(マシン名)\home\hogehoge\MMVC_Trainer-main
STEP4
今回はColabからTrainerを引き継いでる前提なので
ドキュメント「2-1. MMVC_Trainerの配置」から「2-3. fine_modelの配置」はスキップできます。
ドキュメント「3. 環境構築」から開始しますが、ここから実行するコマンドが増えたり確認事項が追加されます。追記したコマンドを実行しないとエラー等で動かないはずです。
※コマンドの大部分はドキュメントより引用。バージョンが変われば手順が変わる可能性大(2023/1/14時点での手順をベースにしています)
cd /home/hogehoge/MMVC_Trainer-main
# 使用するライブラリをインストールするために必要な前提のインストール
sudo apt install python3-pip -y
sudo apt install cmake -y
sudo apt install nvidia-utils-510 -y
sudo apt install espeak -y
# “使用ライブラリ"を定義リストに基づいてインストール
pip install ––upgrade -r requirements_wsl2.txt
# python パス通し
sudo apt install python-is-python3
# "monotonic_align” インストール
cd monotonic_align
python setup.py build_ext ––inplace
cd ..
# CUDA インストール[バージョン指定が重要。詳しくは後述]
wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.1.1/local_installers/cuda-repo-wsl-ubuntu-11-1-local_11.1.1-1_amd64.deb
sudo dpkg -i cuda-repo-wsl-ubuntu-11-1-local_11.1.1-1_amd64.deb
sudo apt-key add /var/cuda-repo-wsl-ubuntu-11-1-local/7fa2af80.pub
sudo apt update sudo apt install cuda -y
# [追記項目]nvidia-cuda-toolkit インストール
sudo apt install nvidia-cuda-toolkit
# [追記項目].bashrcにexportを追記
vim ~/.bashrc
# .bashrc 最終行辺りに追記 (“cuda-xx.x"のバージョン番号の調整は導入タイミング次第で記述調整を忘れずに)
export PATH=/usr/local/cuda-11.3/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-11.3/lib64:$LD_LIBRARY_PATH
# [追記項目/重要]トレーニング開始時に出現するエラー "CPU training is not allowed.” への対策。
sudo ln -s /usr/lib/wsl/lib/libcuda.so.1 /usr/local/cuda/lib64/libcuda.so
# [追記項目]このタイミングでWSLの再起動を推奨。一旦WSLコンソールから退出
exit
# Windows cmd.exe側でWSL再起動を実行
wsl.exe ––shutdown
# GPU確認
# GPUが認識されていることやメモリ量等を確認する
# [追記項目]また、インストールされているCUDA toolkitのバージョン確認を行う。重要なのは"nvcc -V"で表示されるバージョンである。補足にて解説
nvidia-smi
nvcc -V
【必読】追記した内容の補足
まず、本来ドキュメントで書かれている手順で進めた際に出てきたエラーを解説します。
WSL上にトレーニング環境を構築し終えた状態で"python train_ms.py -c 以下略"でトレーニングを開始すると
"AssertionError: CPU training is not allowed." というエラーが表示されますが
公式ドキュメントのエラー対処方法では“Colabでの対処方法”しか掲載されておらず、ローカル環境でこのエラーが表示された場合の対処法が記されていませんでしたので、自主的にこのエラーを調査した際の情報と対処出来た手順を説明します。
まずこのエラーはpytouchのtorch.cuda.is_available()を用いてCUDAによる計算が利用可能であるかどうかを調べていますが、これはCUDAドライバがしっかり導入されていようとFalseを返す(未対応のようなエラーを返す)場合があり、その条件は
・pytouch側で制御をサポートしているCUDAバージョンと一致していない
・WSL固有のCUDAライブラリである"/usr/lib/wsl/lib/libcuda.so.1"が本家CUDA側のライブラリ"/usr/local/cuda/lib64/libcuda.so"とリンクしていない
・【恐らく関連性あり】ホストPC側のCUDA ToolkitがWSL上のpytouch側が対応していないバージョンがインストールされている
事でも同じようにFalseを返してしまい、結果的に処理が開始されない原因となっていました。
この3つの問題を最低でも解決しない限りは "AssertionError: CPU training is not allowed." エラーが返ってきてしまい、学習が開始できません。
続いて対処方法です。
【対処方法】pytouch側で制御をサポートしているCUDAバージョンと一致していない
これは今後のアップデートでバージョンが更新される恐れがあるので現時点でのバージョンを書いておいても意味がないと思うのでpytouch側が要求しているCUDAバージョンを特定する方法もついでに書いておきます。
まあ、単純に"MMVC_Trainer-main"フォルダ内にある"requirements_wsl2.txt"に書かれている"torch=="に記載されているcu113等の数字を見れば良いだけですね。
2023/01/14 - Mainブランチ"時点では以下の通り
torch==1.10.2+cu113
torchvision==0.11.3+cu113
torchaudio==0.10.2+cu113
この場合はcu113 = 11.3ですね。
上記の # CUDA インストール ではドキュメントそのままの表記で載せてしまいましたが、ここはバージョンアップと共に取得してくるリポジトリを変更する必要が出てくるかもしれませんね。
ちなみに # GPU確認 で追加でバージョンを確認するコマンドを追加しておきました。これは他所でもよく言われている事ではありますが nvidia-smiとnvcc -Vで確認できるCUDAバージョン表記は
nvidia-smi
# NVIDIAドライバー側が対応している"最大のCUDAバージョン"表記
nvcc -V
# 現環境に導入されてアクティブになっている"コンパイラドライバー"バージョン表記
であり、上記のpytouchに対応させるには nvcc -Vの方で確認できるバージョンを確認する必要があります。 nvidia-smiはあくまで物理的にGPUを認識出来ているのかどうかを確認する程度に留めたほうが良いでしょう。
【対処方法】WSL固有のCUDAライブラリである”/usr/lib/wsl/lib/libcuda.so.1"が本家CUDA側のライブラリ"/usr/local/cuda/lib64/libcuda.so"とリンクしていない
元はStack Overflowで問題提議されていたものになります。
WSLは通常のPCにOSをインストールした時とは異なる特殊な動作をしているおかげでCUDA等にアクセスする為のライブラリ群はWSL専用の独自の調整が施されたライブラリが用意されているようですが、どうやらそれが本家CUDAがインストールされているライブラリにリンクされていない事で正しく機能していないようです。
現在もこのような問題が発生しているようで、対処法は
【Stack Overflow上の回答を翻訳】
私の場合、wsl2のCUDAが格納されている場所にあるlibcuda.soに/usr/lib/wsl/libcuda.so.1をリンクすることでこの問題を解決しました。
> Homer Simpson
リンク問題を解決する際に、このコマンド sudo ln -s /usr/lib/wsl/libcuda.so.1 /usr/local/cuda/lib64/libcuda.so を使用しました。
> Rashi Abramson
という事で上記コマンドを実行してリンクを再設定すればこの問題を解決できます。
【対処方法】ホストPC側のCUDA ToolkitがWSL上のpytouch側が対応していないバージョンがインストールされている
これは恐らくpytouch側の問題と関連性があると思われるので書いておきます。もしかしたら不要かもしれませんが。
私の環境の場合、以前「Stable Diffusionのような既存モデルをFine-Tuningする」事を行ったので、その時最新だったCUDA Toolkit 11.6が導入されていましたが、2023/1/14時点では11.3を使用するようなのでNVIDIA公式様側の対応するバージョンのツールをインストールしておきました。
ちなみにCUDA Toolkitは複数バージョンの共存が可能で既に別バージョンが導入されていてもインストールは可能です。ただし環境変数は最後にインストールを実行したバージョンに合わせて"CUDA_PATH"が調整されるっぽいので、別のCUDAバージョンを用いたツール等で作業することがあるならツールによってはコマンドを調整するか環境変数を自身で編集する必要が出てくるかもしれません。
という事でこの問題を解決する為の手順は上記の通りとなります。この3つの対策を行う事で AssertionError: CPU training is not allowed. は解決出来るはずです。
STEP5
「4. 設定ファイルを書き換える」の手順を忘れずに。
Colab側で調整した設定のままではお使いのPCに搭載しているGPUによってはメモリオーバーで間違いなくクラッシュするのでtrain_config.jsonの"batch_size"調整を忘れずに。無論、Colabマシンで利用できるGPUメモリよりも容量のあるGPUをお持ちなら問題はありませんが。
私の環境ではGTX1080と旧世代組でもメモリ量はある程度余裕がありましたが、デフォルトの"10"では7.2~8GB以上とオーバーすることがあるらしく、クラッシュしてしまったので"8"に調整することで6.6~7.3GB前後の使用量に抑えてクラッシュすることも無くなりました。
また、クラッシュ時は Out of memory 等のエラー表記が無いパターンがあるようなので参考用のエラーログを貼っておきます。 以下のようなエラーが出た場合でも"batch_size"をお使いのGPUメモリ容量に合わせて調整するだけで問題なく実行できる場合もある事をお忘れなく。
Traceback (most recent call last):
File “train_ms.py”, line 360, in
main()
File “train_ms.py”, line 63, in main
mp.spawn(run, nprocs=n_gpus, args=(n_gpus, hps,))
File “/usr/local/lib/python3.8/dist-packages/torch/multiprocessing/spawn.py”, line 230, in spawn
return start_processes(fn, args, nprocs, join, daemon, start_method=‘spawn’)
File “/usr/local/lib/python3.8/dist-packages/torch/multiprocessing/spawn.py”, line 188, in start_processes
while not context.join():
File “/usr/local/lib/python3.8/dist-packages/torch/multiprocessing/spawn.py”, line 150, in join
raise ProcessRaisedException(msg, error_index, failed_process.pid)
torch.multiprocessing.spawn.ProcessRaisedException:
–– Process 0 terminated with the following error:
Traceback (most recent call last):
File “/usr/local/lib/python3.8/dist-packages/torch/multiprocessing/spawn.py”, line 59, in _wrap
fn(i, args) File “/home/xxxxxx/MMVC_Trainer-main/train_ms.py”, line 170, in run train_and_evaluate(rank, epoch, hps, [net_g, net_d], [optim_g, optim_d], [scheduler_g, scheduler_d], scaler, [train_loader, eval_loader], logger, [writer, writer_eval]) File “/home/xxxxxx/MMVC_Trainer-main/train_ms.py”, line 204, in train_and_evaluate (z, z_p, m_p, logs_p, m_q, logs_q), vc_o_r_hat = net_g(x, x_lengths, spec, spec_lengths, speakers, target_ids) File “/usr/local/lib/python3.8/dist-packages/torch/nn/modules/module.py”, line 1102, in _call_impl return forward_call(input, *kwargs) File “/usr/local/lib/python3.8/dist-packages/torch/nn/parallel/data_parallel.py”, line 166, in forward return self.module(inputs[0], *kwargs[0]) File “/usr/local/lib/python3.8/dist-packages/torch/nn/modules/module.py”, line 1102, in _call_impl return forward_call(input, **kwargs)
File “/home/xxxxxx/MMVC_Trainer-main/models.py”, line 497, in forward
vc_o_hat = self.dec(vc_z_hat * vc_y_mask, g=target_g)
File “/usr/local/lib/python3.8/dist-packages/torch/nn/modules/module.py”, line 1102, in _call_impl
return forward_call(*input, *kwargs) File “/home/xxxxxx/MMVC_Trainer-main/models.py”, line 287, in forward xs += self.resblocksiself.num_kernels+j
File “/usr/local/lib/python3.8/dist-packages/torch/nn/modules/module.py”, line 1102, in _call_impl
return forward_call(*input, **kwargs)
File “/home/xxxxxx/MMVC_Trainer-main/modules.py”, line 220, in forward
x = xt + x
RuntimeError: CUDA error: unknown error
CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect.
For debugging consider passing CUDA_LAUNCH_BLOCKING=1.
STEP6
WSL環境での"Tensorboard使用"について
Tensorboardは、WSL-Ubuntuをセットアップした直後は導入されていないので
sudo pip install tensorflow
でインストールを済ませれば後はドキュメント通りの起動方法で問題なくアクセス出来ます。
WSL環境での"onnx"形式への変換について
これも事前にセットアップが必要です。
sudo pip install onnx onnxsim onnxruntime
これら3つのパッケージがインストールされていないとonnx_export.pyの処理がコケます。特にエラー無く変換できるはずです。まあ書くまでも無いとは思いますが、念のため。
余談: WSL環境へ移行したTrainerを再度Colabへ移行するには
GoogleDrive上に残されているTrainerフォルダを削除せずそのままにした状態で、既にWSL環境上に上記のステップを踏んで移行した
前提で「その状態でWSL環境で学習を実行したが、またColab側で学習を続行したい」場合、再開に必要な必要なフォルダは
logs/自身が指定したモデル名
のみです。モデルが格納されているフォルダをそのままGoogleDrive上にある同一のフォルダを差し替えれば問題なく続行できます。
なお、主に学習再開に最低限必要なデータは
G_latest_99999999.pth
D_latest_99999999.pth
config.json
等である為、途中の成果を記録したG_xxxxx.pthは容量を喰うのでGoogleDriveに投げる前にどこかに退避させるか削除した上でアップロードすると良いでしょう。
あとがき
以上で解説は終了です。後のMMVCバージョンアップでしっかりと対策されそうな内容ですが、ご参考までに。
