Beat This! — MLX

CPJKU/beat_this (final0 checkpoint; "Beat This! Accurate Beat Tracking Without DBN Postprocessing", Foscarin, Schlüter & Widmer, ISMIR 2024) converted to MLX for Apple Silicon. Frame-wise beat and downbeat tracking (50 fps) with minimal peak-picking postprocessing — no DBN — plus a tempo estimate from the beat intervals.

Runs with the open schism-mlx package — weights, config, and an MLX implementation you can actually call:

from schism_mlx.analyze.beat_this import BeatThis

model = BeatThis.from_pretrained("schism-audio/beat-this-mlx")
result = model.detect("song.wav")          # any length, any sample rate
print(result.tempo)                        # BPM estimate
print(result.beats[:8])                    # beat times in seconds
print(result.downbeats[:4])                # downbeat times in seconds

beat_prob, downbeat_prob = model.frame_probabilities("song.wav")  # 50 fps

Conversion & verification

  • Weights are the original float32 final0 checkpoint (~20M params), tensor-renamed with convs permuted to MLX's channels-last layout, and the q/k projections permuted per head from the interleaved (GPT-J) rotary pairing to the equivalent half-split rotate-half convention. No quantization, no finetuning.
  • Verified end to end against the reference implementation (beat-this pip package): max frame-logit difference 9.1e-5 across synthetic test signals, 4.5e-5 on real drum audio from schism-audio/e-gmd, 3.4e-5 on a 56 s piece stitched from overlapping 30 s chunks exactly like the reference split_predict_aggregate. Peak-picked beat, downbeat, and tempo outputs are identical to the reference on every test signal, including the full 44.1 kHz file-input path.
  • The log-mel frontend (22.05 kHz, 128 mels, log1p(1000 x)) is reimplemented in numpy and verified against the reference LogMelSpect (max diff 1.6e-5; the slaney filterbank replicates float32 torch.linspace bit-exactly) — no torch dependency at inference time.
  • ~22 ms per 30 s chunk on an M5 Max (RTF 0.0007).

Precision note: on M5-class GPUs, MLX silently runs float32 matmuls at TF32-class precision (ml-explore/mlx#3860). schism_mlx disables this on import; if you load these weights with your own MLX code, set MLX_ENABLE_TF32=0 to match the reference implementation.

Like the reference pipeline, audio is downmixed to mono, resampled to 22.05 kHz, and processed in 1500-frame (30 s) chunks with 6-frame borders discarded; downbeats are snapped to the nearest beat ("minimal" postprocessing — the paper's headline configuration).

License

MIT, inherited from the source repository (code and released weights). Model by the Institute of Computational Perception, JKU Linz; MLX conversion by schism-audio.

Downloads last month
17
Safetensors
Model size
20.3M params
Tensor type
F32
·
MLX
Hardware compatibility
Log In to add your hardware

Quantized

Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Paper for schism-audio/beat-this-mlx