Text-to-Audio
MLX
Safetensors
qwen3
apple-silicon
quantized
music-generation
text-to-music
minimax-music3
4-bit precision
Instructions to use elishabjm/MiniMax-Music3-MLX with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use elishabjm/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 elishabjm/MiniMax-Music3-MLX
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
| """Pont MLX pour le language_model de MiniMax-Music3. | |
| Le pipeline diffusers n'utilise du Qwen3ForCausalLM que trois points de contact : | |
| language_model.model.embed_tokens(ids) | |
| language_model.model(inputs_embeds=..., past_key_values=..., use_cache=True) | |
| language_model.lm_head(hidden) | |
| Cette classe les reimplemente sur un modele MLX quantifie. Le reste du pipeline | |
| (transformer flow-matching, RVQ depth decoder, vocoder) reste en torch/MPS. | |
| Les tenseurs echanges par pas de decodage sont minuscules, la conversion via numpy | |
| ne pese rien face au forward du modele. | |
| """ | |
| import time | |
| from collections import defaultdict | |
| from pathlib import Path | |
| from types import SimpleNamespace | |
| import mlx.core as mx | |
| import numpy as np | |
| import torch | |
| from mlx_lm.models.cache import make_prompt_cache | |
| from mlx_lm.utils import load_model | |
| STATS = defaultdict(float) | |
| COUNTS = defaultdict(int) | |
| class timed: | |
| def __init__(self, key): | |
| self.key = key | |
| def __enter__(self): | |
| self.t = time.perf_counter() | |
| def __exit__(self, *exc): | |
| STATS[self.key] += time.perf_counter() - self.t | |
| COUNTS[self.key] += 1 | |
| def report(): | |
| if not STATS: | |
| return | |
| width = max(len(k) for k in STATS) | |
| print("\nprofil MLX bridge:") | |
| for key in sorted(STATS, key=STATS.get, reverse=True): | |
| print(f" {key:<{width}} {STATS[key]:7.1f}s {COUNTS[key]:>6} appels") | |
| def _to_mlx(tensor, dtype=mx.bfloat16): | |
| return mx.array(tensor.detach().float().cpu().numpy()).astype(dtype) | |
| def _to_torch(array, device, dtype): | |
| return torch.from_numpy(np.array(array.astype(mx.float32))).to(device=device, dtype=dtype) | |
| class _Embedding: | |
| def __init__(self, bridge): | |
| self._bridge = bridge | |
| def __call__(self, ids): | |
| b = self._bridge | |
| with timed("embed"): | |
| flat = mx.array(ids.detach().cpu().numpy().reshape(-1).astype(np.int64)) | |
| out = b.mlx_model.model.embed_tokens(flat) | |
| out = _to_torch(out, b.device, b.dtype) | |
| return out.reshape(*ids.shape, -1) | |
| class _Inner: | |
| """Expose `.embed_tokens` et l'appel forward attendus par le pipeline.""" | |
| def __init__(self, bridge): | |
| self._bridge = bridge | |
| self.embed_tokens = _Embedding(bridge) | |
| def __call__(self, inputs_embeds=None, past_key_values=None, use_cache=True, **kwargs): | |
| b = self._bridge | |
| cache = past_key_values | |
| if cache is None: | |
| cache = make_prompt_cache(b.mlx_model) | |
| with timed("lm.in"): | |
| h = _to_mlx(inputs_embeds) | |
| with timed("lm.forward"): | |
| out = b.mlx_model.model(None, cache=cache, input_embeddings=h) | |
| mx.eval(out) | |
| with timed("lm.out"): | |
| hidden = _to_torch(out, b.device, b.dtype) | |
| return SimpleNamespace(last_hidden_state=hidden, past_key_values=cache) | |
| class MlxLanguageModel: | |
| def __init__(self, mlx_path, device, dtype=torch.bfloat16): | |
| self.mlx_model, self.mlx_config = load_model(Path(mlx_path), lazy=False) | |
| self.device = torch.device(device) | |
| self.dtype = dtype | |
| self.config = SimpleNamespace(**self.mlx_config) | |
| self.model = _Inner(self) | |
| self._last_hidden_mlx = None | |
| def lm_head(self, hidden): | |
| with timed("lm_head"): | |
| logits = self.mlx_model.lm_head(_to_mlx(hidden)) | |
| mx.eval(logits) | |
| with timed("lm_head.out"): | |
| return _to_torch(logits, self.device, torch.float32) | |
| def to(self, *args, **kwargs): | |
| return self | |
| def eval(self): | |
| return self | |