Metadata-Version: 2.5
Name: gamemlx
Version: 0.1.0
Summary: Pure MLX inference package for GAME (vocal MIDI extraction) on Apple Silicon
License: MIT
Requires-Python: >=3.10
Requires-Dist: click
Requires-Dist: huggingface-hub
Requires-Dist: librosa
Requires-Dist: mido
Requires-Dist: mlx>=0.26
Requires-Dist: numpy<2
Requires-Dist: pyyaml
Requires-Dist: safetensors
Requires-Dist: soundfile
Description-Content-Type: text/markdown

# gamemlx

Pure [MLX](https://github.com/ml-explore/mlx) inference for
[GAME](https://github.com/openvpi/GAME) (Guided Automatic Music Extraction) —
vocal → MIDI, running on Apple Silicon GPU. Numerically aligned with the
torch reference; **fp32 output is bit-comparable on the test set (20/20 files,
all onset/offset/pitch diffs 0.0000) and ~9.4× faster than torch CPU.**

## Install

```bash
uv tool install gamemlx   # or: pip install gamemlx
```

## Quick start

```bash
# download weights (HF: baicai1145/GAME-MLX-medium, ModelScope fallback) and extract
gamemlx extract vocals.wav -m medium --language zh

# local model dir, fp16, custom decoding params
gamemlx extract song/ -m ./weights/GAME-1.0-medium-mlx \
    --precision fp16 --language zh --tempo 120 \
    --seg-threshold 0.2 --seg-radius 0.02 --est-threshold 0.2 \
    --t0 0 --nsteps 8 --output-dir out/
```

Python API:

```python
from gamemlx import load_model, extract

model, lang_map = load_model("medium", precision="fp32")
mids = extract(model, "vocals.wav", language="zh", rng_seed=42)
```

## Models

| alias | HuggingFace | files |
|---|---|---|
| `small` / `medium` / `large` | `baicai1145/GAME-MLX-{small,medium,large}` | config.yaml, lang_map.json, weights(.fp16).safetensors |

Weights convert 1:1 from official GAME checkpoints (torch state_dict keys kept
verbatim). First use downloads to `~/.cache/gamemlx`; ModelScope mirrors are
used automatically when HF is unreachable.

## Alignment & performance (vs GAME torch CPU, 20-file set)

| precision | sequence match | max pitch diff | max onset/offset diff |
|---|---|---|---|
| fp32 | 20/20 identical | 0.0000 | 0.0000 s |
| fp16 | 19/20 (one borderline d3pm flip, analyzed) | 0.0011 | 0.0000 s |

| engine | total inference (20 files) | avg / file | peak RSS |
|---|---|---|---|
| torch CPU (32-true) | 32.19 s | 1.609 s | 971 MB |
| **gamemlx fp32** | **3.44 s** | **0.172 s (9.4×)** | 616 MB |
| gamemlx fp16 | 4.76 s | 0.238 s | 441 MB |

Details: [docs/ALIGNMENT.md](docs/ALIGNMENT.md), [docs/BENCH.md](docs/BENCH.md).

## Notes

- d3pm sampling randomness is injectable (`rng_matrices` / `--rng-seed`) for
  reproducible comparisons against torch.
- fp32 recommended for exact parity; fp16 saves memory (~111MB wired) with
  sub-0.002 pitch deviation.
