音楽生成ライブラリMagentaをDockerで動かして自動採譜してみる

4 min read読了の目安(約3800字

最近機械学習を使った自動音楽生成に取り組み始めました。
音楽生成ライブラリで最も有名なのものとしてGoogle ResearchのMagentaがあります。

https://magenta.tensorflow.org/

Magentaは特定の機能をもつライブラリというよりは、研究によって生まれたプロダクト集のようなものです。
機能例としては以下のようなものが挙げられます。

  • sketch rnn: 音楽生成
  • Tensor2Tensor: 系列から系列データを生成するライブラリ
  • Onsets and Frames: ピアノとドラムの音源からの楽譜(midi)生成

Magentaのインストール自体はワンコードで済ませられるのですが、機械学習ライブラリとしてTensorFlowのバージョン1が必要なため、Cudaのバージョンによってはすんなりインストールできません。また、公式のDockerイメージも配布されていましたが、公式のサポートは打ち切られており、手元の環境では動作しませんでした。

そこでDockerイメージを自前で作ってサクッとGPU環境が構築できるようにするというのが今回の趣旨です。

著者の開発環境

OS: Ubuntu20.10(Kubuntu)
CPU:Intel i5 Gen7
GPU:Geforce RTX3090
Cudatoolkit:11.3 

RTX3000シリーズではCuda toolkitが11.0以降しか入れることができないため、そのままだとTensorFlow-v1はすんなりインストールできませんでした。magentaに限らずRTX3000シリーズでTensorFlow-v1を使う方には参考になると思います。

Dockerfileの作成

以下ではDockerはインストール済みであることを前提とします。また、Dockerの設定によってはdockerコマンドの前にsudoをつける必要があります。

Dockerfile

# From tensorflow/tensorflow:1.14.0-gpu-py3 

#RTX3000series need this container 
From nvcr.io/nvidia/tensorflow:21.04-tf1-py3 

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get upgrade -y  &&\
    apt-get install -y build-essential libasound2-dev libjack-dev portaudio19-dev &&\ 
    pip install magenta &&\
    mkdir -m 777 /working && \
    cd /working &&\
    git clone https://github.com/tensorflow/magenta.git &&\
    chmod -R 777 magenta &&\
    cd magenta &&\
    pip install -e . &&\
    mkdir -m 777 /tmp/numba_cache

# set permission to numba_cache to use numba in non-root

ENV NUMBA_CACHE_DIR=/tmp/numba_cache

EXPOSE 8888
WORKDIR /working

tensorflow純正のイメージはGeforce3000シリーズでは現状うまく動作しなかったため、nvidiaが提供しているtensroflowのイメージを使用します。また内部でパーミッションをいじっていますが、これは後々にrootではないユーザとしてログインして使用するためです。

DockerImageをビルドする

dockerfileが置いてあるディレクトリで以下のコマンドを実行してビルドします。なお、イメージ名を「magenta_nv」としていますが、これは任意で変更可能です。
docker build -t magenta_nv:latest .
ビルドに成功すれば環境構築はこれで完了です。

Onsets and Framesで自動採譜を試す

実際にmagentaのプログラムを動かす手順は以下のようになります。

  1. データのinput、output用のディレクトリを用意する
  2. 必要な学習済みモデルを用意する
  3. 以上2つのディレクトリをマウントしてdockerを実行する
  4. docker内でプログラムを実行する

ここでは例としてOnsets and Framesを用いたピアノ音源からのmidi自動採譜を試してみます。
ディレクトリ構成は以下の通りです。

├── build_docker.sh
├── data
│   └── source.wav #音源ファイル
├── Dockerfile
├── maestro_checkpoint # 学習済みモデル
│   └── train
│       ├── checkpoint
│       ├── model.ckpt.data-00000-of-00001
│       ├── model.ckpt.index
│       └── model.ckpt.meta
└── run_docker.sh

dataディレクトリには入出力データが保存されます。
maestro_checkpointには学習済みモデルをmagentaのgithubにあるリンクから落としてきて解凍したものを配置します。(注)クリックするとダウンロードされます

run_docker.shを以下のように作成し、dockerコンテナを実行します。

WORKDIR=working

docker run -it --rm \
--gpus all \
-p 8888:8888 \
--user $(id -u):$(id -g) \
-v /etc/group:/etc/group:ro \
-v /etc/passwd:/etc/passwd:ro \
-v /etc/shadow:/etc/shadow:ro \
-v /etc/sudoers.d:/etc/sudoers.d:ro \
--mount type=bind,source="$(pwd)",target=/${WORKDIR}/work \
magenta_nv:latest

ここではdocker内のユーザグループをホスト側のPCでのユーザグループと一致させています。これにより、docker内で生成されたmidiファイルの所有者がユーザと一致し、コンテナから抜けてもユーザの権限で編集が可能となります。逆にこれをせずにrootで動かすと、ホスト側でもroot権限なしでは編集ができないため共用サーバーだとかなり面倒なことになります。

bash run_docker.shでコンテナ内に入ったら、workディレクトリに移動し、プログラムを実行します。

cd work
onsets_frames_transcription_transcribe --model_dir maestro_checkpoint/train data/source.wav

dataディレクトリにsource.wav.midiというmidiファイルが作成されていれば成功です。ここではworkディレクトリが丸々ホストからマウントされているのでコンテナから抜けてもdataはホスト側のPCに保存されます。

終わりに

音楽生成ライブラリのmagentaの開発環境をDockerで構築しました。
今回の要点をまとめると以下のようになります

  • GeForce3000シリーズではNvidia製のTensorfrowイメージを使用
  • ホストのグループidなどの情報をdockerコンテナにマウントし、パーミッションを制御

ちなみに単純に1曲だけ採譜したいだけであればブラウザで実行できる環境が公開されているのでそちらを使用することをお勧めします。

https://piano-scribe.glitch.me/

音楽生成については色々ワクワクする部分も多くこれから少しづつ触っていき、情報を共有できたらと思います。本記事が同志の方々の参考になれば幸いです。

おまけ

MusicTransformerで遊んでいたら、いい感じのピアノアレンジができたので聴いてみてください。

https://www.youtube.com/watch?v=3YW0kx4XTFw