Instructions to use PocketAiHub/MiniMax-Music3-MLX with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use PocketAiHub/MiniMax-Music3-MLX with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] huggingface-cli download --local-dir MiniMax-Music3-MLX PocketAiHub/MiniMax-Music3-MLX
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
File size: 2,730 Bytes
11b0ce1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | #!/usr/bin/env python3
"""Generate a song with the native Apple-Silicon MiniMax-Music3 MLX port."""
from __future__ import annotations
import argparse
import wave
from pathlib import Path
import numpy as np
from minimax_mlx_model import SAMPLE_RATE, MiniMaxMusic3MlxPipeline
def bounded_float(minimum: float, maximum: float):
def parse(value: str) -> float:
parsed = float(value)
if not minimum <= parsed <= maximum:
raise argparse.ArgumentTypeError(f"must be between {minimum:g} and {maximum:g}")
return parsed
return parse
def bounded_int(minimum: int, maximum: int):
def parse(value: str) -> int:
parsed = int(value)
if not minimum <= parsed <= maximum:
raise argparse.ArgumentTypeError(f"must be between {minimum} and {maximum}")
return parsed
return parse
def write_wav(path: Path, audio: np.ndarray) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
pcm = np.clip(audio.T, -1.0, 1.0)
pcm = np.round(pcm * 32_767).astype("<i2")
with wave.open(str(path), "wb") as output:
output.setnchannels(2)
output.setsampwidth(2)
output.setframerate(SAMPLE_RATE)
output.writeframes(pcm.tobytes())
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--prompt", required=True, help="Musical direction/caption")
lyrics = parser.add_mutually_exclusive_group(required=True)
lyrics.add_argument("--lyrics", help="Lyrics text; use [Instrumental] for no vocals")
lyrics.add_argument("--lyrics-file", type=Path, help="UTF-8 text file containing lyrics")
parser.add_argument("--seconds", type=bounded_float(10, 300), default=60.0)
parser.add_argument("--steps", type=bounded_int(1, 30), default=30)
parser.add_argument("--seed", type=bounded_int(0, 2**31 - 1), default=7)
parser.add_argument("--model-dir", type=Path, default=Path(__file__).resolve().parent)
parser.add_argument("--output", type=Path, default=Path("song.wav"))
args = parser.parse_args()
lyrics_text = (
args.lyrics_file.read_text(encoding="utf-8") if args.lyrics_file else args.lyrics
)
assert lyrics_text is not None
def progress(stage: int, message: str) -> None:
print(f"[{stage}/5] {message}", flush=True)
pipeline = MiniMaxMusic3MlxPipeline(args.model_dir, progress)
audio = pipeline.generate(
args.prompt.strip(),
lyrics_text.strip(),
args.seconds,
args.steps,
args.seed,
progress,
)
progress(5, f"Writing {args.output}…")
write_wav(args.output, audio)
print(args.output.resolve())
if __name__ == "__main__":
main()
|