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.4

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.4
File Size Uploaded Provenance Actions
lytk-0.6.4.tar.gz 1.0 MB With provenance Details for lytk-0.6.4.tar.gz

Built distributions (wheels)

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

Total release size: 28.8 MB

Release files / lytk-0.6.4.tar.gz

Download URL lytk-0.6.4.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
c239e597d5cdec7037e1cc3b068011e6d1aa7f0865099a2a7891c17cec362cc9
BLAKE2b-256 checksum
How to use checksums
2b0243e10c448725eafb7e8a53be74a51a66f152a2914cd17e3cf2c433a54487
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 25, 2026.

Transparency log

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

Download URL lytk-0.6.4-cp310-abi3-win_amd64.whl
Size 3.6 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
cc7c69f3632cf5e557339f8673c5c3c799033287776a606148bfe2c1ae6ba294
BLAKE2b-256 checksum
How to use checksums
8d9ecd3894777d485b3a1c4b798710498683b4e84f2f18c67cc69659272cf7d8
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 25, 2026.

Transparency log

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

Download URL lytk-0.6.4-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
603f8542d737f378d5d46482e1e3335e250e1ccd4e145f4f4aa7fc51169c5536
BLAKE2b-256 checksum
How to use checksums
ec2b238b106076900c2ec601e99a4d5e421c2c1950eb22e59d1c7480bfdec3dc
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 25, 2026.

Transparency log

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

Download URL lytk-0.6.4-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
faecf2f59a83a76fec79b261175b40ca79bb7c72e31ab23a90af0e55e1ef7891
BLAKE2b-256 checksum
How to use checksums
21f30fd1033dbba0c18c3371fac74c69ef750f0288e09fa78496647f008a2f02
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 25, 2026.

Transparency log

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

Download URL lytk-0.6.4-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
2ec6a8f7dd3d2122adf246a9194b8ffdc1927ec5f356ed478a260c0317b8e48b
BLAKE2b-256 checksum
How to use checksums
ab3566d74856bfe77f57be8d06ddba073f167d12868a6706f8d3b6e7ef116522
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 25, 2026.

Transparency log

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

Download URL lytk-0.6.4-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
ed807a99974e423e2b65aee23c1370f3526a29d5e0893c921fc2ecd1dd30a71e
BLAKE2b-256 checksum
How to use checksums
f45b2559ae2ae73a27eda55a4da4eaab9b1d2fc889dd7cfe28f49723f4d3fdd7
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 25, 2026.

Transparency log

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

Download URL lytk-0.6.4-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
59fc11fafe8f1ce416df6de6a5a190a4481a543fbe45a2970768a0b776c6f5c0
BLAKE2b-256 checksum
How to use checksums
c6b8d1336f713a6c11c3cc7a4cf1ef3a2bb272eeeaad6f4d62f48402e1bd02e4
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 25, 2026.

Transparency log

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

Download URL lytk-0.6.4-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
b0f21123e6e0255642032e53a3b6228ac100fd911a00e794064519f3fdc882a7
BLAKE2b-256 checksum
How to use checksums
f3a960e14a213b6f277e0d68d597edaaf951659e2efaa9dbbfe9e208c3e8cf25
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 25, 2026.

Transparency log

Security for lytk 0.6.4

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.4.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 25, 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