オープンウェイトの音楽生成AI MiniMax-Music3 を RunPod で動かして13曲作った(実測値まとめ)
2026年8月14日にオープンウェイト公開された音楽生成モデル MiniMax-Music3 を、RunPodでGPUを借りて動かしてみました。
環境構築から生成まで一通りやって、1.72時間・約137円で13曲できました。VRAMやRAMの実際の使用量、生成にかかる時間、ハマりどころをまとめます。
TL;DR
- 歌詞+音楽の説明文から、**最長5分のフル楽曲(歌入り)**を生成するモデル
- 既存曲を参考にしたカバー生成はできない(音声を入力するパラメータが存在しない)
- 実測: VRAM 23.3GB・システムRAM 26GB・リアルタイム比 0.47倍
- VRAMは曲の長さに依存しないので、24GBのGPUで足りる
- ただしシステムRAMは32GB以上必要。ここを見落とすと最安GPUを選んで詰む
- 出力は 44.1kHz / 16bit / ステレオ(READMEの「32kHz」は誤り)
- 5分の曲1本あたり 約14円
MiniMax-Music3 とは
約11Bパラメータの音楽生成モデルです。構成が特徴的で、
Global LLM (8B, Qwen3-8B由来) ← 曲の長期構造・意味を担当
↓
Local LLM (0.6B) ← フレーム内の音響細部を担当
↓
隠れ状態の融合
↓
Flow Matching (2.4B)
↓
Flow-VAE Decoder (123M)
↓
ステレオ音声
離散トークンだけからデコードするのではなく、Global / Local 両LLMの最終隠れ状態を融合してFlow Matchingに渡します。この連続表現が発声のニュアンスや楽器の質感を保つ、という設計です。
できること
- 歌詞 + 音楽説明文 → 最長5分のフル楽曲。イントロ〜Aメロ〜サビ〜間奏〜アウトロの構造が崩れない
- 歌詞に構造タグを書ける:
[intro][verse][pre-chorus][chorus][post-chorus][bridge][instrumental][solo][outro] - 日本語の歌詞も歌う
- シード指定で再現可能
説明文は3層の Structured Caption で書くと制御が効きます。
- Global Metadata: ジャンル / BPM / キー / 感情の推移 / 聴取シーン / 音質
- Vocal Details: 声の性別 / 音色 / 歌い方 / ハモリ / エフェクト
- Arrangement: 主要楽器 / セクションごとの変化 / グルーヴ / 空間処理
できないこと
既存の曲を読み込んで、それを参考に新しい曲を作ることはできません。
期待している人が多そうなので実装を確認しました。diffusersパイプラインが受け付ける入力は次の4つだけです。
InputParam("prompt", required=True) # 音楽の説明文
InputParam("lyrics", required=True) # 歌詞
InputParam("audio_duration", default=60.0)
InputParam.template("generator") # シード
音声を渡すパラメータが存在しません。
紛らわしいのが condition_encoder/config.json で、
{"input_sampling_rate": 24000, "input_hop_length": 960}
いかにも音声を食いそうに見えますが、実装は forward(hidden_states) で、これはLLMのフレームレートを潜在フレームレートに変換するための係数でした。音声入力ではありません。
カバー生成はMiniMaxの商用APIにある music-cover という別モデルの機能(audio_url / audio_base64 / cover_feature_id を受け取る)で、オープンウェイト化されていません。公式クラウドの music-3.0 エンドポイントですら歌詞+説明文のみです。
その他の制約
- CUDA必須(CPU推論不可)
- ストリーミング生成は非対応
- プロンプトは5,000トークンまで、生成は9,000フレーム(6分)まで
- タグやBPM指定は「誘導」であって「保証」ではない(公式が明記)
なぜRunPodを使ったか
ウェイトが約26GBあり、これがシステムRAMに乗るためです。
公式READMEには「CPUオフロードを使えば8GBのビデオカードでも動く」とありますが、これはVRAMの話です。CPUオフロードはVRAMに載りきらないウェイトをシステムRAMに置く仕組みなので、VRAMを節約した分はそのままRAMの消費になります。
手元のRTX 3060機(VRAM 12GB / システムRAM 30GB)では、RAM側が先に限界に達しました。VRAMではなくシステムRAMがボトルネックになるというのが、このモデルを動かす上での最重要ポイントです。
GPU選定
RunPodの当日価格(VRAM 24GB以上)です。
| GPU | VRAM | RAM | vCPU | Community | Secure |
|---|---|---|---|---|---|
| RTX A5000 | 24GB | 25GB | 9 | $0.16/h | $0.27/h |
| RTX 3090 | 24GB | 125GB | 16 | $0.22/h | $0.50/h |
| RTX A6000 | 48GB | 50GB | 9 | $0.33/h | $0.53/h |
| RTX 4090 | 24GB | 41GB | 6 | $0.34/h | $0.74/h |
| A40 | 48GB | 50GB | 9 | $0.35/h | $0.44/h |
| L4 | 24GB | 50GB | 12 | $0.44/h | $0.49/h |
| L40 | 48GB | 94GB | 8 | $0.69/h | $0.82/h |
選定条件は2つ。VRAMだけで決めてはいけません。
- VRAM ≥ 24GB
- システムRAM ≥ 32GB(ウェイト26GBがホストRAMを通過するため)
この2条件を掛けると、最安の RTX A5000 は RAM 25GB なので脱落します。単価だけ見て選ぶと、ウェイトが載らずに詰みます。
第一候補は RTX 4090 Community($0.34/h)にしましたが、当日は 4090 / A6000 / A40 / L40 の Community が全滅していて、実際に取れたのは RTX A6000 / Secure / $0.53/h でした。VRAM 48GBあるのでオフロード設定が一切不要になり、結果的に検証がシンプルになりました。
割り当てリソースは cgroup で確認する
free や nproc はホスト全体の値を見せてくるので当てになりません。
$ free -g
total used free
Mem: 503 81 139 # ホスト全体の値
$ cat /sys/fs/cgroup/memory.max
49999998976 # = 46.6GiB ← 実際の割り当て
$ cat /sys/fs/cgroup/cpu.max
765000 100000 # = 7.65 vCPU
ディスク速度
コンテナディスク (/) 2.9 GB/s
/workspace(ネットワーク) 535 MB/s
ネットワーク側は5倍遅いですが、27GBのロードで50秒程度の差にしかなりません。そもそも30GBのコンテナディスクには27GBのモデルが入らないので、モデルは /workspace に置きます。
環境構築
イメージ
runpod/pytorch:1.1.0-rc.154-cu1281-torch280-ubuntu2204
確定した構成:
| パッケージ | バージョン |
|---|---|
| Python | 3.12.13 |
| torch | 2.8.0+cu128 |
| CUDA | 12.8 |
| transformers | 5.15.0 |
| diffusers | 0.40.0.dev0 |
インストール
diffusersは未マージのPRブランチが必要です(2026年8月時点)。所要22秒。
pip install --no-cache-dir \
"git+https://github.com/huggingface/diffusers@dafe3733fcfdbf3c48915fe77be3aef65b5d6a2d" \
transformers accelerate soundfile "huggingface_hub[cli]"
ハマりどころ① python と python3 が別物
このイメージには torchが入った /usr/local/bin/python と、素の /usr/bin/python3 が両方あります。pip は前者に紐づいています。
python -c "import torch" # OK
python3 -c "import torch" # ModuleNotFoundError: No module named 'torch'
セットアップスクリプトを python3 で書いていて、「pip installは成功しているのにimportできない」で少し悩みました。
ハマりどころ② リポジトリの半分は diffusers では使わない
素直に全部落とすと 54GB になります。
18G qwen_7B/ ← SGLang経路用。diffusersでは不要
16G language_model/ ← 必要
9.2G flowmatching_vae.pth ← SGLang経路用。不要
9.1G transformer/ ← 必要
1.3G rvq_depth_decoder/ ← 必要
470M dav.pth ← 不要
209M vocoder/ ← 必要
98M condition_encoder/ ← 必要
modular_model_index.json が参照するのはサブフォルダの7コンポーネントだけなので、除外すれば 54GB → 27GB です。ダウンロード自体は65秒でした。
hf download MiniMaxAI/MiniMax-Music3 --local-dir /workspace/model \
--exclude "qwen_7B/*" --exclude "*.pth"
--exclude "qwen_7B/*" "*.pth"と続けて書くと、2つ目が「そういう名前のファイル」と解釈されて404になります。--excludeは都度書いてください。
ハマりどころ③ ローカルパスを渡してもHubから再ダウンロードされる
modular_model_index.json の7コンポーネント全部に、こうハードコードされています。
"pretrained_model_name_or_path": "MiniMaxAI/MiniMax-Music3"
このため、
pipe = ModularPipeline.from_pretrained("/workspace/model") # ローカルパスを渡したのに
としても中身はHubを見に行き、27GBを再ダウンロードします。これに気づかずディスクを埋めました。
対策は2つセットで打ちます。
# 1. JSON内のパスをローカルに書き換える
for name, spec in data.items():
if isinstance(spec, list) and len(spec) == 3 and isinstance(spec[2], dict):
spec[2]["pretrained_model_name_or_path"] = MODEL_DIR
# 2. 事故ってもHubに出て行かないようにする
export HF_HUB_OFFLINE=1
ハマりどころ④ 公式READMEのサンプルコードが落ちる
READMEにはこう書いてあります。
sf.write("song.wav", audio.T.float().cpu().numpy(), pipe.sampling_rate)
しかし実際に返ってくるのは torch tensorではなくnumpy配列なので、
AttributeError: 'numpy.ndarray' object has no attribute 'float'. Did you mean: 'flat'?
で落ちます。生成を60秒かけて完走した後、最後の1行で死ぬので注意してください。
data = audio.T
if hasattr(data, "cpu"):
data = data.float().cpu().numpy()
else:
data = np.asarray(data, dtype=np.float32)
ハマりどころ⑤ サンプリングレートがREADMEと違う
READMEは全編を通して「32 kHz 16-bit stereo」と書いていますが、pipe.sampling_rate が返すのは 44100 です。出力WAVを確認しても、
44100 Hz 2 ch PCM_16
でした。44.1kHz / 16bit / ステレオが正しい値です。
生成
コード
import os
os.environ["HF_HUB_OFFLINE"] = "1"
import torch, soundfile as sf
from diffusers import ModularPipeline
pipe = ModularPipeline.from_pretrained("/workspace/model")
pipe.load_components(dtype=torch.bfloat16)
pipe.to("cuda")
audio = pipe(
prompt=prompt, # 音楽の説明文
lyrics=lyrics, # 歌詞(構造タグ付き)
audio_duration=90.0,
generator=torch.Generator("cuda").manual_seed(7),
output="audios",
)[0]
歌詞の書き方
構造タグは必ず単独行に置きます。実装のコメントに明記があります。
Structure tags such as
[verse]or[chorus]must each be on their own line; text on the same line as a leading tag is dropped by the checkpoint's input contract.
[verse]
ぼくは まだ ちいさいけれど
ゆめだけは でっかいんだ
[chorus]
はやく おとなに なったなら
どこへだって いけるんだ
[verse] ぼくは まだ... のようにタグと同じ行に書くと、その本文は黙って捨てられます。
説明文の書き方(実際に使ったもの)
Global Metadata: Genre modern kids pop anthem for an animated film.
Tempo 150 BPM, driving and danceable. Key D major, bright and upbeat.
Production profile: glossy modern pop mix, punchy drums, wide stereo.
Vocal Details: Lead vocal is a spirited young child, bright and cheeky.
Gang-vocal singalong chorus with children and adults.
Arrangement: Four-on-the-floor kick with loud handclaps. Marimba plays
the main hook. Bouncy synth bass, plucky synth stabs, layered hand
percussion, punchy brass stabs.
BPMやキーは効きますが、あくまで誘導です。厳密に一致するとは限りません。
実測値
ロード時間
| 工程 | 秒 |
|---|---|
from_pretrained |
0.2 |
load_components |
5.7 |
to("cuda") |
31.9 |
| 合計 | 37.8 |
ロード直後で VRAM 21.87GB、ホストRAM 28.64GB。
なおロード時間はページキャッシュの状態で大きく変動します(実測で 10.6秒 〜 91.0秒)。ネットワークストレージから27GBを読むと、それだけで約50秒かかるためです。
生成
| ジャンル | 指定尺 | 実際の尺 | 生成秒 | リアルタイム比 | VRAMピーク |
|---|---|---|---|---|---|
| 英語アコースティックポップ | 30s | 30.02s | 62.3 | 0.482 | 23.12 GB |
| 日本語J-POPバラード | 90s | 70.88s | 150.1 | 0.472 | 23.23 GB |
| 日本語シティポップ | 90s | 64.76s | 138.4 | 0.468 | 23.23 GB |
| Lo-fiインスト | 90s | 75.69s | 160.9 | 0.470 | 23.28 GB |
| ミュージカル | 180s | 144.9s | 321.3 | 0.451 | 23.3 GB |
| ミュージカル | 300s | 239.7s | 553.8 | 0.433 | 23.3 GB |
ここから3つのことが読み取れます。
① VRAMは曲の長さに依存しない
23.1〜23.3GBでほぼ一定です。Flow Matchingを200フレームの窓に区切ってdenoiseしているため、5分の曲でもVRAMは増えません。
つまり 48GBは過剰で、24GBのGPUで足ります。RTX 3090($0.22/h)や RTX 4090($0.34/h)で同じことができるはずです。ただしシステムRAM 32GB以上は必須です。
② audio_duration は「上限」であって「目標」ではない
90秒を指定して出てきたのは 64.76〜75.69秒、300秒指定で 239.7秒でした。公式の説明通りです。
Generation may finish before this limit when the model emits an end-of-audio token.
狙った尺にしたいなら、audio_duration を長めに取った上で歌詞の分量で調整します。 尺の指定だけで曲を伸ばすことはできません。
③ 生成時間は尺にほぼ比例する
リアルタイム比が 0.43〜0.48 に収まっているので、**「欲しい秒数 ÷ 0.47」**で所要時間を見積もれます。
5分(300秒)のフル楽曲なら約640秒 ≒ 10.6分。A6000 なら 約14円/曲です。
費用と後片付け
実費
| 項目 | 値 |
|---|---|
| GPU | RTX A6000 / Secure Cloud |
| 単価 | $0.53/h |
| 稼働時間 | 1.72 時間 |
| 実費 | 約 $0.91(約137円) |
| 生成 | 13曲・合計約24分 |
環境構築に約6分(pip 22秒 + モデルDL 65秒 + 不要ファイル削除とパス修正)、残りは生成と試行錯誤です。1曲あたり約10円。
RunPodは stop では課金が止まらない
ここは要注意です。 停止中のPodもストレージ課金が続き、しかも稼働中の倍単価($0.20/GB/月)になります。以前これでPodを放置して月$121(約18,000円)を発生させたことがあります。
終わったら必ず terminate(DELETE) して、残り0件を確認するまでがセットです。
for pod_id in targets:
api("DELETE", f"/pods/{pod_id}")
time.sleep(6)
remaining = api("GET", "/pods")
print(f"VERIFIED: {len(remaining)} pod(s) remain")
if remaining:
sys.exit(2)
セッションが切れても課金が止まるよう、Podの外にタイムアウト強制terminateを置いておくと安心です。Podの中に置くと、terminate時に自分ごと消えて後始末が完了しません。
モデルDLはGPUを借りる前にできるか
できます。ネットワークボリュームを先に作り、CPU専用PodでダウンロードしてからGPU Podに付け替えれば、GPUの課金時計はモデルが揃ってから回り始めます。
ただし単発なら割に合いません。
- DL 65秒 = $0.53/h × 65s ≒ $0.01
- ネットワークボリューム 60GB = 月$4.2 が置くだけで発生し続ける
- ボリュームはデータセンター固定なので、そのDCに空きGPUが無いと詰む(今回まさにCommunityが全滅した)
繰り返し使うならボリューム、単発なら都度DL で良いと思います。
RunPod APIの注意点
新しい rpa_ 形式のAPIキーは GraphQL では 403 になります。 RESTを使ってください。
curl https://rest.runpod.io/v1/pods -H "Authorization: Bearer $RUNPOD_API_KEY"
エンドポイント一覧は GET /v1/openapi.json で取れますが、GPU価格を引くAPIはRESTには無いので、価格は料金ページを見るしかありません。
Pod作成時、条件を厳しくしすぎると落ちます。
{"error":"create pod: This machine does not have the resources to deploy your pod"}
特に minVCPUPerGPU に注意。RTX 4090は6 vCPUしかないので、8を要求すると弾かれます。実用的には、候補GPUを安い順に並べて空きがあるものを順に試すのが確実です。
CANDIDATES = [
("NVIDIA GeForce RTX 4090", "COMMUNITY", 0.34),
("NVIDIA RTX A6000", "COMMUNITY", 0.33),
("NVIDIA A40", "COMMUNITY", 0.35),
("NVIDIA RTX A6000", "SECURE", 0.53),
]
for gpu, cloud, price in CANDIDATES:
try:
pod = api("POST", "/pods", build(gpu, cloud))
break
except urllib.error.HTTPError:
continue
まとめ
MiniMax-Music3 は「歌詞と説明文からフル楽曲を作る」ことに特化したモデルで、そこはよくできています。日本語の歌詞も歌ってくれました。一方で既存曲を参考にする用途には対応していないので、そこが必要なら商用APIの music-cover を見ることになります。
環境構築で一番効いた知見は、VRAM要件だけを見てGPUを選ばないことでした。CPUオフロード系のモデルはVRAMをシステムRAMに逃がす仕組みなので、ローVRAM構成ほどRAMを食います。「8GBのGPUでも動く」という記述は、RAMが潤沢にあることが暗黙の前提になっています。
実測値をまとめておきます。
| 項目 | 実測 |
|---|---|
| 必要VRAM | 23.3GB(曲の尺に依存しない) |
| 必要システムRAM | 26GB+α(32GB以上を推奨) |
| ロード時間 | 37.8秒(キャッシュ次第で10〜91秒) |
| 生成速度 | リアルタイム比 0.47倍 |
| 出力 | 44.1kHz / 16bit / ステレオ |
| コスト | 5分の曲で約14円 |
なお商用利用する場合は MiniMax-Music3 COMMUNITY LICENSE により UI上に「MiniMax-Music3」の表示が必要です。ストック素材や動画制作に使う場合は確認してください。