Music Transfomerで曲の続きを生成

2023/05/14に公開
1

はじめに

今回はGoogleが提供する、音楽を生成するライブラリ"magenta"のMusic Transfomerを使用して曲の続きを生成する方法について記載しようと思います。なお、実行環境は、前回投稿したWSL2でMusic Transfomer実行環境をセットアップをもとに実行しています。

また、本記事は、以下のmagentaの公式Colabノートブックをローカル環境で実行するように改造している形です。
https://colab.research.google.com/notebooks/magenta/piano_transformer/piano_transformer.ipynb

環境

WSL2がセットアップされていることが前提です。
ホストOS: Windows11
WSL2: 5.10.16.3-microsoft-standard-WSL2(Ubuntu 20.04)
CPU: 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz 2.30 GHz
GPU: NVIDIAグラボを搭載していますが、今回はCPUで実行します。(うまくWSL2環境でGPUセットアップできなかった)

ライブラリバージョン
以下のバージョンで動かせていることが確認できています。

$ pip install tensorflow==1.15.2
$ pip install magenta==1.3.1
$ pip install tensor2tensor==1.15.5
$ pip install tensorflow-probability==0.7.0
$ pip install tensorflow-datasets==3.0.0
$ pip install pip install numpy==1.19.5

必要なもの

曲の続きを生成するためには以下のファイルが必要です。準備方法について解説していきます。

  • Music Transfomerの学習済みcheckpointファイル
  • midiファイル

Music Transfomerの学習済みcheckpointファイル

ローカル環境にcheckpointファイルをダウンロードしておきます。一回ダウンロードしておくと、生成速度が速くなって快適です。

checkpointのダウンロードのコマンドは以下から実行できます。

 gsutil -q -m cp -r gs://magentadata/models/music_transformer/checkpoints/*

ダウンロードするためにgsutilsがインストールされている必要があります。まだインストールしていない方は以下を参考にインストールしましょう。
https://cloud.google.com/storage/docs/gsutil_install?hl=ja#linux

以下の6つのファイルがダウンロードできてれば成功です。

melody_conditioned_model_16.ckpt.data-00000-of-00001
melody_conditioned_model_16.ckpt.index
melody_conditioned_model_16.ckpt.meta
unconditional_model_16.ckpt.data-00000-of-00001
unconditional_model_16.ckpt.index
unconditional_model_16.ckpt.meta

midiファイル

次に曲の入り口のmidiファイルを用意します。適当に以下などのmidiファイルをフリーでダウンロードできるサイトから準備してもよいですし、Cakewalk by BandLabのようなDAWソフトで自分でmidiファイルを作って、自分の好きなところから続きを生成してもよいと思います。
https://musmus.main.jp/music_midi.html

曲の続きを生成するscript

準備ができたら、曲の続きを生成するscriptを作成しましょう。基本的には、以下から必要な箇所だけ持ってくるだけで生成できました。
https://colab.research.google.com/notebooks/magenta/piano_transformer/piano_transformer.ipynb

必要な関数を定義して、

def input_generator():
    global targets
    global decode_length
    while True:
        yield {
            "targets": np.array([targets], dtype=np.int32),
            "decode_length": np.array(decode_length, dtype=np.int32)
            }

# モデルの出力がidなので、それをMIDIにデコードする関数
def decode(ids, encoder):
    ids = list(ids)
    if text_encoder.EOS_ID in ids:
        ids = ids[:ids.index(text_encoder.EOS_ID)]
    return encoder.decode(ids)

checkpointのパスを設定してあげて推定器を構築し、

model_name = "transformer"  # モデル
hparams_set = "transformer_tpu"  # ハイパーパラメータ
ckpt_path = "<checkpoint_path>"  # チェックポイント
# エンコーダー生成用のクラス
class PianoPerformanceProblem(score2perf.Score2PerfProblem):
  @property
  def add_eos_symbol(self):
    return True

problem = PianoPerformanceProblem()
unconditional_encoders = problem.get_feature_encoders()

# モデル(推定器)を構築
run_config = trainer_lib.create_run_config(hparams)
estimator = trainer_lib.create_estimator(
    model_name,
    hparams,
    run_config,
    decode_hparams=decode_hparams
    )

# 推定
input_fn = decoding.make_input_fn_from_generator(input_generator())  # 入力を生成する関数
predicted = estimator.predict(
    input_fn,
    checkpoint_path=ckpt_path  # チェックポイントを読み込む
    )

あとは入力のmidiファイルを入力として続きを生成してあげます。

targets = unconditional_encoders['targets'].encode_note_sequence(
    primer_ns)

詳細なスクリプトは以下のリポジトリ内で公開していますので、よかったら参照してください。
https://github.com/ihpolyphe/MusicTransfomer

実際に"夜に駆ける"を入力に続きを生成させてみました。前半は微妙ですが、後半は結構いい感じに生成できています。よかったら聞いてみてください。
https://www.youtube.com/watch?v=iN5pxr1-WGs

心拍数#822(蝶々P feat.初音ミク)のサビ10小節から続きをMusic Transfomerで作曲
https://www.youtube.com/watch?v=2iqwuNqX7hY

GitHubで編集を提案

Discussion

ozoz

この記事はもう古いです。何一つ真似してもうまくいきませんでした。。。。
MacOS 14.4.1 AppleM1