Skip to main content

Harmonica

An independent reproduction of Harmonica: Accurate and Lightweight Instrument-Agnostic Music Transcription (Ou, Martel, Hennessy-Priest, Cho; arXiv:2609.04640). Audio of one pitched instrument goes in and its notes come out as MIDI, with no instrument label anywhere.

This is not the authors' code. Everything here was rebuilt from the paper. Where the paper leaves a detail unspecified, we filled it in with our own assumptions, so this implementation is not guaranteed to match the authors' exactly.

Transcribe a recording

uvx harmonica-amt infer song.wav                 # writes song.mid
uvx harmonica-amt infer song.flac -o out.mid     # choose where the MIDI goes
uvx harmonica-amt infer song.wav --model my-run/checkpoint_latest.ckpt  # your own model

Input can be WAV, FLAC, MP3, or OGG. Inference runs on a GPU if there is one, otherwise on the CPU. Until the package is on PyPI, run it from GitHub: uvx --from git+https://github.com/z-huang/harmonica harmonica infer song.wav. (PyPI's harmonica is a geophysics package, hence harmonica-amt; once installed, the command is available as both.)

Models

--model takes one of Table 1's sizes or the path of a checkpoint. Each size ships with the decoding thresholds its development-set sweep chose. Scores are the mean OnP / OnPOff / Frm over the paper's eight test sets:

Variant Params Ours Paper
nano 25K .791 / .524 / .763 .808 / .547 / .773
small 131K .835 / .603 / .804 .854 / .638 / .815
medium (default) 654K .862 / .660 / .827 .879 / .687 / .838
large 3.1M .877 / .688 / .843 .891 / .713 / .848
x-large 14.7M .882 / .694 / .843 .895 / .721 / .852

docs/results.md breaks the scores down by test set.

Python

from harmonica import Harmonica

model = Harmonica()  # the bundled medium, on the GPU if there is one
notes = model.transcribe("song.wav")
notes.save_midi("song.mid")

for onset, offset, pitch in zip(notes.onsets, notes.offsets, notes.pitches):
    print(f"{onset:.2f}-{offset:.2f}s  MIDI {pitch}")

The model loads once, so reuse a Harmonica for many recordings. It also takes a NumPy array with its sample rate, model.transcribe(audio, 44100), and Harmonica(model, device=..., onset_threshold=..., frame_threshold=...) picks another model, device, or thresholds.

Reproduce the paper

uv sync                                      # Python 3.12+, a CUDA GPU
harmonica prepare --workers 16               # index the eight corpora
harmonica train --size medium                # one row of Table 1
harmonica eval --size medium \
    --checkpoint outputs/harmonica-medium/checkpoints/checkpoint_latest.ckpt

Citation

This repository reproduces the following paper; please cite it:

@article{ou2026harmonica,
  title   = {Harmonica: Accurate and Lightweight Instrument-Agnostic Music Transcription},
  author  = {Ou, Longshen and Martel, H{\'e}ctor and Hennessy-Priest, Joe and Cho, Taemin},
  journal = {arXiv preprint arXiv:2609.04640},
  year    = {2026}
}

Metadata

Release files for harmonica-amt 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for harmonica-amt 0.1.0
File Size Uploaded Provenance
harmonica_amt-0.1.0.tar.gz 69.5 MB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for harmonica-amt 0.1.0
File Interpreter ABI Platform
harmonica_amt-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 139.0 MB

Release files / harmonica_amt-0.1.0.tar.gz

Download URL harmonica_amt-0.1.0.tar.gz
Size 69.5 MB
Tags Source
SHA-256 checksum
How to use checksums
ad9f217dd608cbaf706b5c6f7b74a9cd80423e3739fb0d9b681c892251f40dd7
BLAKE2b-256 checksum
How to use checksums
10f1547d9ddeabd64d1abd24295956eabaaac54e162fb5dac932046fadb8afd2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / harmonica_amt-0.1.0-py3-none-any.whl

Download URL harmonica_amt-0.1.0-py3-none-any.whl
Size 69.5 MB
Tags Python 3
SHA-256 checksum
How to use checksums
e46b2897e7cd94df72cdd0100be043086b2240347a1b5a9d52dce8fdf10c6674
BLAKE2b-256 checksum
How to use checksums
22e4822ab121aa364a173776abd762aa75b83b6adbc2ae16eb2bc5ef29772232
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for harmonica-amt 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page