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

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

Built distributions (wheels)

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

Total release size: 28.8 MB

Release files / lytk-0.6.3.tar.gz

Download URL lytk-0.6.3.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
ecd08555d684d11ce0501ad88d20fc2913a9a327f4ace57c6c8fd81439fc5d2f
BLAKE2b-256 checksum
How to use checksums
bac353e840a49c8bbb4da9dfb52c7f728797ced1b9cda32414fb02dd7086d6ca
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.3-cp310-abi3-win_amd64.whl

Download URL lytk-0.6.3-cp310-abi3-win_amd64.whl
Size 3.6 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
549441eedbbc94cf49dcd7ac25f4deb1c09cdd03f8cdff4d833c88ac097fbd68
BLAKE2b-256 checksum
How to use checksums
f0ede44a448b7f2896879f3188d88906938caab2a884ac7367c0c17e740f2cd9
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.3-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL lytk-0.6.3-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
ccb87b47f0fcd4d715c80eaaec49ccc1b2597872615c741c62ab6163ac293f02
BLAKE2b-256 checksum
How to use checksums
9994a13c99a4162206967ea4264a9f566050f96ea8cc349cf958bde97778fc2e
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.3-cp310-abi3-musllinux_1_2_aarch64.whl

Download URL lytk-0.6.3-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
e86a53a5a218fa2b642956c146574c65c4e0e5e254115204cfade024df5c8455
BLAKE2b-256 checksum
How to use checksums
dadfcfbb5cae7a353ed2be5e952a7494b7ea7fd55b1da3f1cd0cc4fc7ad3135a
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.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL lytk-0.6.3-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
d1261f798099e25e16b232139dbd4b16155a34c9cf7755d2d43c7941609564bd
BLAKE2b-256 checksum
How to use checksums
820249f831c7e807d05d5345abc50a62dfb6a4cedb6a3aaa91d4bf0e9e029623
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.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL lytk-0.6.3-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
10b981518f05aa282021257973d82cb64cbaa90ea943ce9fd1d0ea1c6af976b3
BLAKE2b-256 checksum
How to use checksums
6659c21a34157f9f0fb3c93c4f2aa04e27a28946d02d3567389b7069d552b617
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.3-cp310-abi3-macosx_11_0_arm64.whl

Download URL lytk-0.6.3-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
e573f7e4e6389933b02f0e673e3a7249e197b71b669422e54f972649fd633585
BLAKE2b-256 checksum
How to use checksums
6c82391de495cedcf0af7ecc95e6d53c81b40ef1f8e6a82a2805991b9d9d8e56
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.3-cp310-abi3-macosx_10_12_x86_64.whl

Download URL lytk-0.6.3-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
5857f162754373c9ffaea46fe92a810fa01feaabcfbed1f62aa01c8080e87e6f
BLAKE2b-256 checksum
How to use checksums
2cf9827193996c09559c6b938986c1d37ab442db876637722468e3214fc22520
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.3

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