Skip to main content

lytk

CI PyPI Python License: MIT

lytk reads and writes symbolic music, and turns it into training data. Scores in LilyPond, MusicXML, MIDI, ABC and Humdrum **kern go through one internal representation, so any format converts to any other. The same scores come out as NumPy note arrays, piano rolls and event sequences, ready for PyTorch or TensorFlow. The core is written in Rust; you use it from Python or from the command line.

Preview release (0.x). Conversion, transforms and the ML pipeline are tested and ready to use. The API can still change before 1.0: notation marks (articulations, ornaments, dynamics) will move from strings to enums.

Why lytk

  • LilyPond is a first-class format. lytk reads real LilyPond files, not a subset: variables, \relative, piano scores with several voices per staff, repeats and voltas, cadenzas, lyrics, chord names and figured bass. It writes them back out too, in any of LilyPond's 12 note-name languages.
  • Conversions are measured, not assumed. Every round trip (LilyPond, MusicXML, ABC, **kern, MIDI) is checked in CI against a test corpus for notes (onsets, durations, sounding pitches), lyrics, chord symbols, dynamics and clefs at their places; stems and beams against the engravers that wrote the files; LilyPond output against LilyPond itself. The results can only improve from one release to the next (the numbers).
  • Built for machine learning. Encoders for note arrays, piano rolls and Performance-RNN event sequences, objective metrics from the muspy family, datasets over folders or JSON Lines records with deterministic (or the records' own) splits and caching, and padded data loaders for PyTorch and TensorFlow.
  • Fast. A Rust core with prebuilt wheels, and a batch converter that uses every core. It transposes LilyPond about 50× faster than python-ly.

Install

pip install lytk                  # every format, transform and representation
pip install "lytk[torch]"         # + PyTorch datasets and data loaders
pip install "lytk[tensorflow]"    # + tf.data datasets and data loaders
pip install "lytk[eval]"          # + generation-evaluation metrics (scipy, FMD)
pip install "lytk[all]"           # everything above

Wheels are prebuilt for Linux, macOS and Windows and cover CPython 3.10 and newer, so no Rust toolchain is needed. PyTorch and TensorFlow are optional and only imported when you ask for a loader.

Quick start

import lytk

score = lytk.from_musicxml("input.xml")      # or from_lilypond, from_midi, from_abc, from_humdrum
score = lytk.transpose(score, semitones=3)   # also invert, retrograde, change_language
lytk.to_lilypond(score, "output.ly")         # or to_musicxml, to_midi, to_abc, to_humdrum
abc = lytk.to_abc(score)                     # without a path, writers return the text

Check LilyPond before you rely on it:

for d in lytk.check_lilypond(text, semantic=True):   # errors and warnings, in source order
    print(d)                                         # 3:12: error: missing `}` [missing-token]
score = lytk.from_lilypond("score.ly", strict=True)  # raises lytk.LilyPondSyntaxError on an error
score.diagnostics                                    # what the reading reported, either way
score.header                                         # every \header field, as a dict
fields = lytk.header_fields(text)                    # …or read from the text: key, value, span

A reader raises lytk.ParseError (a ValueError) when its input cannot be read, and OSError when the file cannot be opened.

Turn a score into arrays:

doc = score.to_music_document()
notes = lytk.to_note_array(doc)        # (N, 4): onset, duration, pitch, velocity
roll = lytk.to_piano_roll(doc)         # (T, 128)
events = lytk.to_event_sequence(doc)   # Performance-RNN event codes
stats = lytk.compute_metrics(doc)      # pitch-class entropy, polyphony, scale consistency, …

Each encoder has an inverse (from_note_array, …). The arrays are ordinary NumPy arrays, and NumPy supports DLPack, so PyTorch, JAX and CuPy can use them without copying:

import torch
tensor = torch.from_dlpack(lytk.to_piano_roll(doc))   # shares the buffer

Build a dataset from a folder of scores in any mix of formats:

from lytk.datasets import FolderDataset

data = FolderDataset("corpus/", cache_dir=".cache")
train, val, test = data.split((0.8, 0.1, 0.1), seed=0)

loader = train.to_pytorch_dataloader("event_sequence", batch_size=32, shuffle=True)
for events, lengths in loader:         # padded batch plus each item's true length
    ...

Scores differ in length, so each batch is padded. The true lengths come back alongside it because 0 is a valid event, pitch and velocity, so padding alone can't tell you where a score ends. to_tensorflow_dataloader works the same way.

A corpus kept as JSON Lines records (id, text, metadata) keeps its ids and its own splits:

from lytk.datasets import RecordsDataset

data = RecordsDataset.from_jsonl("scores.jsonl", split_field="split", on_error="skip")
splits = data.split()                  # {"train": …, "valid": …, "test": …}, as recorded
loader = splits["train"].to_pytorch_dataloader("note_array", batch_size=32, return_ids=True)
for arrays, lengths, ids in loader:
    ...

The package also installs a lytk command:

lytk convert input.xml -o output.ly           # formats are taken from the extensions
lytk convert corpus/ -o out/ -f xml -j 8      # a whole folder, in parallel
lytk transpose input.ly -s 3 -o up.ly
lytk flatten score.ly -o flat.ly              # inline every \include
lytk check score.ly --semantic                # report the errors of LilyPond files
lytk info input.mxl

It also inverts, reverses, changes note-name languages, compares scores (lytk diff) and runs JSON batch jobs; lytk --help lists every command and docs/cli.md describes them.

Formats

Format Extensions Read Write
LilyPond .ly .ily ✓ ✓
MusicXML .xml .musicxml ✓ ✓
Compressed MusicXML .mxl ✓ ✓
MIDI .mid .midi ✓ ✓
ABC .abc ✓ ✓
Humdrum **kern .krn ✓ ✓

docs/import-export.md lists what each reader and writer keeps. MusicXML is the most complete. MIDI export plays a score the way LilyPond's own MIDI does (dynamics, articulations, grace notes, repeats, pedal, lyrics); slurs and ornaments are not performed.

Not there yet

  • Tablature, unpitched notes and fretboard diagrams (LilyPond drums are read as their General MIDI keys on a percussion staff).
  • Performed MIDI is quantized less reliably when its tempo is far from the file's own, when chords are released unevenly, or at a low resolution.
  • Non-traditional key signatures, cross-staff notes (\change Staff), and Humdrum spine splits (*^, *v). Files that use spine splits are rejected with an error.
  • The ABC and **kern writers produce one stream per staff, so two voices sharing a staff are not kept separate.
  • MEI is planned after 1.0.

Documentation

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md, and SECURITY.md for reporting vulnerabilities.

Acknowledgements

lytk builds on a lot of prior work in music notation software. Its LilyPond parser uses the tree-sitter-lilypond grammar by Nathan Whetsell (MIT, notice in src/tree-sitter/LICENSE). Its design also owes a lot to LilyPond, python-ly, music21, muspy, abjad, symusic and MuseScore.

License

MIT, see LICENSE. The test fixtures are third-party scores under their own terms (tests/fixtures/README.md).

Metadata

Release files for lytk 0.6.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 lytk 0.6.0
File Size Uploaded Provenance
lytk-0.6.0.tar.gz 1.0 MB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for lytk 0.6.0
File
lytk-0.6.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
lytk-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl CPython 3.10 abi3 Linux musl 1.2+ x86-64 Details
lytk-0.6.0-cp310-abi3-musllinux_1_2_aarch64.whl CPython 3.10 abi3 Linux musl 1.2+ ARM64 Details
lytk-0.6.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
lytk-0.6.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
lytk-0.6.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
lytk-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 28.8 MB

Release files / lytk-0.6.0.tar.gz

Download URL lytk-0.6.0.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
42032ac19f63c1f6aa46036258159a9a09fb5de074e81e3128dbe38a73f4b651
BLAKE2b-256 checksum
How to use checksums
d5d7c22a9d7970f89b97a795c10217a6dee549ac81895ba2cff8cc0e7483ec97
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / lytk-0.6.0-cp310-abi3-win_amd64.whl

Download URL lytk-0.6.0-cp310-abi3-win_amd64.whl
Size 3.6 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
db340f7a5b1ccb790ad39a1e3a8dec29c5a8afcff7ad57426e26334d81c09ab3
BLAKE2b-256 checksum
How to use checksums
2316dbcfc89dfd5a433713cf66eaa67704421645d0db7e6c69aac2c285690b15
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / lytk-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL lytk-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl
Size 4.4 MB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
9529922bf2d27f688f6b8d1e6233dff968c57a0adcb1da7f7a2e4a9bf8640847
BLAKE2b-256 checksum
How to use checksums
403c309805d68b38001ed7d64c9773e667a88958019e2a3bd3f2d00958cb301f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / lytk-0.6.0-cp310-abi3-musllinux_1_2_aarch64.whl

Download URL lytk-0.6.0-cp310-abi3-musllinux_1_2_aarch64.whl
Size 4.2 MB
Tags CPython 3.10 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
51bc84ac856bd0504077a12d2e7455018e1d1a49e8cdc929bbbf057fe7d03598
BLAKE2b-256 checksum
How to use checksums
57a5e78e9d57628a53c76953763177559a61b166bda138db4b6654dfccbd8aa2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / lytk-0.6.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL lytk-0.6.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 4.0 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
e5334dff82946a82dfbc87dca7be9db8f2f02dc906e41ee3ed3e9b65e22f0766
BLAKE2b-256 checksum
How to use checksums
d0d9a23f1b0c49cf7ab3c3fbcc9cda2160f7c555947efa036a500b25c92a243e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / lytk-0.6.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL lytk-0.6.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 4.0 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
9f83f0d8478b733ae4fa9f84ea63ec1e1660315c53d08cbda2c6a52e04b3cfcd
BLAKE2b-256 checksum
How to use checksums
71ce19a8c34a467c9355705e5fb5e15e3010e8bf198c8dd8f3c79948e0ab0a22
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / lytk-0.6.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL lytk-0.6.0-cp310-abi3-macosx_11_0_arm64.whl
Size 3.7 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
9cbb2420435624faffba628f5bd598aade89361299e8f81936ffe0f78f8b0039
BLAKE2b-256 checksum
How to use checksums
6811e5a8a1dcd747db1f120f2e11d44a1ffbba94805ba5f339f4debe474cc5b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / lytk-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl

Download URL lytk-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl
Size 3.8 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
7c9631e80ea15c18a38f8f63c8453ded0b4b51c9ab2910ee33ad9b7c6c5cefba
BLAKE2b-256 checksum
How to use checksums
2203430331953c1cd2c136dcdf1b444945066d8ced87b251b3a9c47760564ba3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for lytk 0.6.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.

Full provenance

All 8 files in this release have been uploaded with provenance metadata.

Select from 8 files

Attestation for lytk-0.6.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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