SqueezeWave 動作メモ(CUDAとROCmで推論を試す)


上記ドキュメントのGPU版です、

目的

CPUで動かすとcode中のaudio tensorがnanになってしまい音声が出力されないのでGPUでも再現されるか確認する
CUDA10.0環境が必須なのでnvidia-docker環境の構築メモも兼ねる

環境構築

docker環境とnvidia-docker2が既にインストール済みであることが前提条件になります
テスト環境はCUDA10.01 + RTX2080TI

ホストマシンのホームディレクトリにリポジトリをclone

git clone https://github.com/tianrengao/SqueezeWave.git
cd SqueezeWave 
git submodule init
git submodule update

トレーニング済みモデル
mel-spectrograms

をダウンロードしてunzipで解凍

ここまではCPU版と同じようにやります。

nvidia-dockerを使ったのでdockerfileを以下のように書きました

FROM nvidia/cuda:10.0-cudnn7-runtime

RUN apt update && apt install -y python3-pip
RUN apt install -y git
RUN git clone https://www.github.com/nvidia/apex
WORKDIR ./apex
RUN pip3 install torch==1.0 matplotlib==2.1.0 numpy==1.13.3 inflect==0.2.5 librosa==0.6.0 scipy==1.0.0 tensorboardX==1.1 Unidecode==1.0.22
RUN python3 setup.py install
tensorboardX==1.1 Unidecode==1.0.22

任意のディレクトリにdockerfileを保存して

$ sudo docker build . -t squeezewave 

NVIDIA Dockerで実行

次にdocker runします、ホストマシンのディレクトリをマウントしているのがポイントです

$ sudo docker run    --runtime=nvidia --rm     -it -v /home/{HOMEディレクトリ名}/SqueezeWave:/SqueezeWave             squeezewave:latest

コンテナに入ったら

# cd /SqueezeWave/
#  python3 inference.py -f <(ls mel_spectrograms/*.pt) -w pretrain_models/L64_large_pretrain  -o .  -s 0.6
/usr/local/lib/python3.6/dist-packages/torch/serialization.py:434: SourceChangeWarning: source code of class 'glow.SqueezeWave' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.
  warnings.warn(msg, SourceChangeWarning)
/usr/local/lib/python3.6/dist-packages/torch/serialization.py:434: SourceChangeWarning: source code of class 'glow.WN' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.
  warnings.warn(msg, SourceChangeWarning)
THCudaCheck FAIL file=/pytorch/aten/src/THC/THCGeneral.cpp line=405 error=11 : invalid argument
./LJ001-0015.wav_synthesis.wav
./LJ001-0051.wav_synthesis.wav
./LJ001-0063.wav_synthesis.wav
./LJ001-0072.wav_synthesis.wav
./LJ001-0079.wav_synthesis.wav
./LJ001-0094.wav_synthesis.wav
./LJ001-0096.wav_synthesis.wav
./LJ001-0102.wav_synthesis.wav
./LJ001-0153.wav_synthesis.wav
./LJ001-0173.wav_synthesis.wav

で推論できます
実行時間は2080Tiでreal 0m9.784sでした、ひとまずGPUでは最低限動くことがわかりました。

https://soundcloud.com/zsjzuobwha2e/sets/squeezewave-inferencepy-output-sound
データはこちらにあります

--is_fp16でFP16を有効にした場合でもreal 0m10.042sだったので性能差はそれほどない感じでした

ROCm-Dockerでやってみる

ROCm3.1+RadeonⅦでやってみます

Dockerfileは以下の通り

FROM rocm/pytorch:rocm3.0_ubuntu16.04_py3.6_pytorch

RUN apt update && apt install -y python3-pip
RUN apt install -y git
#RUN git clone https://www.github.com/nvidia/apex
#WORKDIR ./apex
RUN pip3 install  matplotlib==2.1.0 numpy==1.13.3 inflect==0.2.5 librosa==0.6.0 scipy==1.0.0 tensorboardX==1.1 Unidecode==1.0.22
#RUN python3 setup.py install
#RUN pip3 install torch==1.0 matplotlib==2.1.0 numpy==1.16.2 inflect==0.2.5 librosa==0.6.0 scipy==1.0.0 tensorboardX==1.1 Unidecode==1.0.22
$  sudo docker build . -t rocm-squeezewave 
$ sudo   docker run --name pytroch_rocm -it  --privileged --rm --device=/dev/kfd --device=/dev/dri --group-add video  -v /home/{ホームディレクトリ名}/SqueezeWave:/SqueezeWave rocm-squeezewave
$ cd /SqueezeWave/
$  python3.6 inference.py -f <(ls mel_spectrograms/*.pt) -w pretrain_models/L64_large_pretrain  -o .  -s 0.6

最低限途中のaudio tensorの生成をするぐらいはできる.

tensor([[[ 0.1525,  0.7336,  0.6206,  ..., -0.4970, -0.6939,  0.8375],
         [-0.0091,  0.4194,  0.7400,  ..., -0.1548, -0.1589,  0.9829],
         [ 0.1160, -0.0903,  0.3936,  ...,  0.4681, -0.8460,  0.1797],
         ...,
         [ 2.7151,  0.2097, -1.7632,  ..., -0.4245,  0.3499, -0.3599],
         [-0.8716, -0.1110,  0.3357,  ..., -0.5838,  0.1851, -1.3772],
         [ 0.2319,  0.9468, -0.4212,  ..., -0.3868,  1.1623, -0.9812]]],
       device='cuda:0')

しかしNVIDIA CUDAでよく使われる線形代数ライブラリであるMAGMAライブラリ依存で実装されている部分がある為推論完走はならなかった

Traceback (most recent call last):
  File "inference.py", line 89, in <module>
    args.sampling_rate, args.is_fp16, args.denoiser_strength)
  File "inference.py", line 58, in main
    audio = squeezewave.infer(mel, sigma=sigma).float()
  File "/SqueezeWave/glow.py", line 266, in infer
    audio = self.convinv[k](audio, reverse=True)
  File "/root/.local/lib/python3.6/site-packages/torch/nn/modules/module.py", line 539, in __call__
    result = self.forward(*input, **kwargs)
  File "/SqueezeWave/glow.py", line 104, in forward
    W_inverse = W.float().inverse()
RuntimeError: inverse: MAGMA library not found in compilation. Please rebuild with MAGMA.

MAGMAをどうにかROCmで動かす方法を検討しないとダメみたいですね
ひとまず無理やりnumpyで置き換えて動かすことにしました。

glow.pyの104行目をコメントアウトする代わりに以下をついかして

  testout= W.cpu().numpy()
  testout=np.linalg.inv(testout)
  W_inverse=torch.from_numpy(testout).to('cuda')

forward()を以下のような感じに書き換えると一応動きます、まあCPUに投げてるので邪道です


    def forward(self, z, reverse=False):
        # shape
        batch_size, group_size, n_of_groups = z.size()
        W = self.conv.weight.squeeze()

        if reverse:
            if not hasattr(self, 'W_inverse'):
                # Reverse computation
                #W_inverse = W.float().inverse()
                testout= W.cpu().numpy()
                testout=np.linalg.inv(testout)
                W_inverse=torch.from_numpy(testout).to('cuda')
                W_inverse = Variable(W_inverse[..., None])
                if z.type() == 'torch.cuda.HalfTensor':
                    W_inverse = W_inverse.half()
                self.W_inverse = W_inverse
            z = F.conv1d(z, self.W_inverse, bias=None, stride=1, padding=0)
            return z
        else:
            # Forward computation
            log_det_W = batch_size * n_of_groups * torch.logdet(W)
            z = self.conv(z)
            return z, log_det_W

同じ条件下で./LJ001-0015.wav_synthesis.wavを一個生成するのに必要な所要時間は
ROCm RadeonⅦでreal 1m6.183s
CUDA RTX2080Tiでreal 0m9.138s
でした

明らかに実用性がない速度なので素直にCUDAを使ったほうがよさそげです。

todo

CPUで動かないのを再検証する