AI・機械学習 python 技術関連

[OpenAI][jukebox]最新の音楽自動生成モデルを動かしてみる

更新日:

概要

人工知能研究の非営利団体「OpenAI」が発表した楽曲生成のAI「Jukebox」ついて解説します。

はじめに

人工知能を研究する非営利団体「OpenAI」が、ニューラルネットワークを使って指定したジャンル・アーティスト・歌詞から楽曲作成可能なAI「Jukebox」を公開しました。

これを使うことで、
マイケルジャクソンにアニソンを作曲させ、歌わせるというようなことが出来るようになります。

今まで、生成系のモデルだと、
動画や画像系が実用レベルまで進んでいましたが、あまり音楽系の生成モデルは記事を見たことがありませんでした。

音声系であれば、DeepVoiceなど合成音声の技術が進んでいましたが、楽曲系は楽器・音色・歌詞・歌声・抑揚・ノイズなど情報量が多く難しい領域でした。

そんな中で、楽曲の再現クオリティのレベルが高い「Jukebox」の登場したので、動かしてみました。

アーキテクチャ

VQ-VAE-2

モデルの構造は、VQ-VAE-2が採用されております。

VQ-VAEは、非GANの生成モデルになります。

画像系の事例になりますが、
現在の最良のGANモデル(BigGAN-deep)に匹敵する高解像度の画像を生成が可能かつ、BigGAN-deepより画像の多様性が優れている特徴を持っております。

VQ-VAE-2はVQ-VAEの進化系であり、
VQ-VAEでは中間表現として、ベクトル量子化を用いて情報を離散的な潜在空間に圧縮していました。

VQ-VAE-2はオリジナルのVQ-VAEと同様にシンプルかつ軽量に保たれていますが、さらに解像度を上げるために階層型の潜在マップを使用しています。潜在表現を異なるスケール毎に階層的に学習します。

「jukebox」はこのアーキテクチャを利用し、
階層的に楽曲データをCNNで圧縮しています。

データセット

このモデルをトレーニング用に、120万曲(うち60万は英語)楽曲をWeb上でクロールし、対応する歌詞とメタデータと組み合わせることでデータセットを作成しております。

メタデータには、アーティスト、アルバムのジャンル、曲の年、および各曲に関連付けられている一般的なムードやプレイリストキーワードが含まれます。

32ビット、44.1 kHzの生のオーディオでトレーニングし、右と左のチャンネルをランダムにダウンミックスしてモノラルオーディオに変換しています。

ジャンルとアーティストの紐づけ

最上位層にある圧縮された楽曲データを使用して、アーティストやジャンルの予測モデルを作成しモデルに情報を付与しています。

歌詞の紐づけ

歌詞の情報をモデルに対応させるために、歌詞表現を生成するエンコーダーを追加し、音楽デコーダーからのクエリを使用して歌詞エンコーダーのキーと値に対応するアテンションレイヤーを追加しています。

実装

インストール

Python3.7を使用し、実行環境を整えます。

# Required: Sampling
conda create --name jukebox python=3.7.5
conda activate jukebox
conda install mpi4py=3.0.3
conda install pytorch=1.4 torchvision=0.5 cudatoolkit=10.0 -c pytorch
git clone https://github.com/openai/jukebox.git
cd jukebox
pip install -r requirements.txt
pip install -e .

# Required: Training
conda install av=7.0.01 -c conda-forge 
pip install ./tensorboardX
 
# Optional: Apex for faster training with fused_adam
conda install pytorch=1.1 torchvision=0.3 cudatoolkit=10.0 -c pytorch
pip install -v --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext" ./apex

生成

アーティスト名、ジャンル、歌詞をインプットして楽曲を生成します。

lyicdict.pyを編集して入力にするかしを歌詞入れます。

# Poems
poems = {
'ozymandias': '''
I met a traveller from an antique land,
Who said—“Two vast and trunkless legs of stone
Stand in the desert. . . . Near them, on the sand,
Half sunk a shattered visage lies, whose frown,
And wrinkled lip, and sneer of cold command,
Tell that its sculptor well those passions read
Which yet survive, stamped on these lifeless things,
The hand that mocked them, and the heart that fed;
And on the pedestal, these words appear:
My name is Ozymandias, King of Kings;
Look on my Works, ye Mighty, and despair!
Nothing beside remains. Round the decay
Of that colossal Wreck, boundless and bare
The lone and level sands stretch far away
'''
}

sample.pyの184行目以降を編集して、ジャンルと歌詞とアーティストの辞書を追加しておきます。

    # Set artist/genre/lyrics for your samples here!
    # We used different label sets i# Poems
poems = {
'ozymandias': '''
I met a traveller from an antique land,
Who said—“Two vast and trunkless legs of stone
Stand in the desert. . . . Near them, on the sand,
Half sunk a shattered visage lies, whose frown,
And wrinkled lip, and sneer of cold command,
Tell that its sculptor well those passions read
Which yet survive, stamped on these lifeless things,
The hand that mocked them, and the heart that fed;
And on the pedestal, these words appear:
My name is Ozymandias, King of Kings;
Look on my Works, ye Mighty, and despair!
Nothing beside remains. Round the decay
Of that colossal Wreck, boundless and bare
The lone and level sands stretch far away
'''
}n our models, but you can write the human friendly names here and we'll map them under the hood for each model.
    # For the 5b/5b_lyrics model and the upsamplers, labeller will look up artist and genres in v2 set. (after lowercasing, removing non-alphanumerics and collapsing whitespaces to _).
    # For the 1b_lyrics top level, labeller will look up artist and genres in v3 set (after lowercasing).
    metas = [dict(artist = "Alan Jackson",
                  genre = "Country",
                  lyrics = poems['ozymandias'],
                  total_length=total_length,
                  offset=offset,
                  ),

sample.pyを実行して楽曲を生成します。
生成にはかなり時間がかかるようで、GPUをnvidiaのv100を使用しても
20秒の楽曲の生成に3時間ほど時間がかかります。

python jukebox/sample.py --model=5b_lyrics --name=sample_5b --levels=3 --sample_length_in_seconds=20 --total_sample_length_in_seconds=180 --sr=44100 --n_samples=6 --hop_fraction=0.5,0.5,0.125

生成後は、
デコードされた楽曲は{name}/level_{level}{name}/level_{level}/data.pth.tarに保存され、
歌詞と楽曲付きのHTMLファイルが{name}/level_{level}/index.htmlに保存されます。
python -m http.serverでhtmlファイルを開くことが出来ます。

もっと長い楽曲を生成したい場合は、
出力済みのデータをオプションで指定することで、短い時間で生成することができます。

python jukebox/sample.py --model=5b_lyrics --name=sample_5b --levels=3 --mode=continue --codes_file=sample_5b/level_0/data.pth.tar --sample_length_in_seconds=40 --total_sample_length_in_seconds=180 --sr=44100 --n_samples=6 --hop_fraction=0.5,0.5,0.125

学習

VQVAEのモデルを学習させます。
事前に{audio_files_dir}に楽曲データを保存しておきます。

mpiexec -n {ngpus} python jukebox/train.py --hps=small_vqvae,small_upsampler,all_fp16,cpu_ema --name=small_upsampler --sample_length 262144 --bs 4 --nworkers 4 --audio_files_dir {audio_files_dir} --labels False --train --test --aug_shift --aug_blend --restore_vqvae logs/small_vqvae/checkpoint_latest.pth.tar --prior --levels 2 --level 0 --weight_decay 0.01 --save_iters 1000

転移学習をする場合は、下記コードで学習済みのVQVAEを再学習させることができます。

mpiexec -n {ngpus} python jukebox/train.py --hps=vqvae,small_prior,all_fp16,cpu_ema --name=pretrained_vqvae_small_prior --sample_length=1048576 --bs=4 --nworkers=4 --bs_sample=4 --aug_shift --aug_blend --audio_files_dir={audio_files_dir} --labels=False --train --test --prior --levels=3 --level=2 --weight_decay=0.01 --save_iters=1000 --model mymodel

おわりに

楽曲生成モデルについて解説しました。
英語の曲のみ対応しているみたいなので、日本語の曲は難しいようですが、
AIが楽曲まで作れる時代になったのですね。

作曲家の仕事を奪う日が近いかもしれないです。

作曲家の方は、逆にこれを利用してAIを自由に使いこなして
楽曲を楽に作れるようになったら面白いかもしれないですね。

-AI・機械学習, python, 技術関連

Copyright© AIなんて気合いダッ! , 2020 All Rights Reserved Powered by AFFINGER5.