Skip to main content

plitzer

A deterministic, resumable dataloader for ML training that reads Parquet directly from local disk or S3. The core is written in Rust and exposed to Python.

The order is a pure function of (seed, epoch) and the dataset. Documents are packed into fixed-length sequences by lanes, which depend on the batch size and never on the GPU count: every sequence is full, with no token dropped and no padding. Resuming mid-epoch is exact, and the sequences stay identical when the GPU count changes.

Status: alpha, 0.1.0. The API and the checkpoint format can still change between minor versions; a checkpoint from another version is refused with a clear error, never misread.

Install

pip install plitzer            # wheels for Linux (x86_64, aarch64), macOS and Windows, CPython 3.11+
pip install "plitzer[torch]"   # with the PyTorch IterableDataset

Quick start

The input is a Parquet dataset with a pre-tokenized list<int32> (or uint32) column.

import numpy as np
import plitzer

loader = plitzer.Loader(
    "s3://bucket/fineweb-edu",          # or a local folder
    seed=0, lanes=512, window=64,        # B lanes, W row groups per window
    seq_len=2048,                        # every row is 2048 real tokens: none dropped, no padding
    budget=8 << 30,                      # bytes of decoded row groups kept in memory
                                         # (4 per token + 8 per document)
    rank=0, world=8,                     # this GPU, of 8
)
while loader.epoch < 3:                  # also right after loader.resume(state)
    for batch in loader:                 # the rest of this epoch; then epoch + 1
        tokens = np.from_dlpack(batch.tokens)    # or torch.from_dlpack, or pyarrow.array
        ...
    state = loader.checkpoint()          # this GPU's part; plitzer.merge(parts) joins all GPUs

With PyTorch (pip install plitzer[torch]), plitzer.torch.Dataset takes the same settings. It reads the rank and world from torch.distributed, and its state_dict() is one global checkpoint that resumes on any number of GPUs:

from torch.utils.data import DataLoader
import plitzer.torch

dataset = plitzer.torch.Dataset("s3://bucket/fineweb-edu", seed=0, lanes=512, window=64,
                                seq_len=2048, budget=8 << 30)
loader = DataLoader(dataset, batch_size=None, num_workers=0)  # each item is one step
while dataset.epoch < 3:                 # also right after dataset.load_state_dict(state)
    for batch in loader:                 # batch.tokens: (lanes per GPU, seq_len) int32
        ...
    state = dataset.state_dict()         # call it on every rank: it gathers all GPUs
# later, on any number of GPUs: dataset.load_state_dict(state)

The state is the position of the next batch the dataset gives, so a loop that prefetches batches before training them skips those on a resume (#22).

S3 credentials come from the usual AWS_* variables, or from storage_options={"endpoint": ..., "region": ...}.

The design, its rationale and the decision log are in docs/design.md.

Benchmarks

plitzer against MosaicML Streaming and Hugging Face datasets, all reading the same FineWeb-Edu-shaped Parquet files (512 row groups, 526 M tokens) through one harness, plitzer.bench.baseline, on 4 CPU cores with the files in the page cache (converted sizes in MiB, tokens lost on a resume at mid-epoch):

loader convert (s) converted (MiB) docs/s Mtokens/s cores CPU ns/token resume (s) exact resume tokens lost
plitzer 0.0 0.0 — 298.5 3.95 13.2 0.34 yes 0
mosaic 27.5 1221.8 23,475 24.1 2.66 110.5 2.79 yes 0
hf 4.8 2008.7 82,952 85.2 0.99 11.6 0.16 yes 0
hf-stream 0.0 0.0 2,329 2.4 1.12 467.0 3.54 no 10,373,481

plitzer reads the Parquet as it is, with no conversion or copy, delivers 3.5× the tokens of hf and 12× those of Mosaic, packs every sequence full with no padding, and resumes exactly. hf still spends less CPU per token (11.6 vs 13.2 ns) and resumes faster (0.16 vs 0.34 s), from the Arrow copy it makes first; both are the next work on speed. --batch is in documents, and plitzer gets the same tokens in each batch (32 sequences of 2048). Method and caveats: design §5.14.

python -m plitzer.bench.baseline DATA --loaders plitzer,mosaic,hf,hf-stream --batch 64 --workers 4

TODO

  • Benchmark baseline: measure MosaicML Streaming and HF datasets on a FineWeb-Edu Parquet sample (conversion time, samples/s, CPU cores used, resume time) (plitzer.bench.baseline, design §5.14)
  • Ordering core: shuffle row groups per epoch, split each window into lane slices, and shuffle each slice (rand_chacha). Property tests:
    • each epoch yields every sample exactly once
    • each lane's slice is one contiguous stretch of storage
    • a saved reference output matches on every OS
  • Lanes: pack each lane's documents into fixed-length sequences, and checkpoint each lane's position. Property tests:
    • resuming at step k matches the tail of an uninterrupted run
    • global batches are identical across GPU counts
  • Lossless packing: cut lane slices by tokens and fill each sequence to exactly L, with lanes running on across epochs, so no token is dropped or padded (was 19.3% lost on FineWeb-Edu lengths)
  • Index: build a row-group index from Parquet footers, with caching
  • I/O: async reads with object_store (local disk and S3, tested against versitygw), plus a prefetch queue capped by bytes
    • read one row group's token column without its footer (local disk and S3)
    • prefetch each GPU's row groups for a window, capped by bytes
  • Python: PyO3 and maturin bindings, a PyTorch IterableDataset with state_dict(), and Arrow PyCapsule export
    • typed checkpoint bytes that merge across GPUs, and a per-GPU session that runs epochs and refuses a mismatched resume
    • bindings: a plitzer wheel exporting batches through DLPack and Arrow
    • plitzer.torch IterableDataset with state_dict() and load_state_dict()
  • End-to-end test: kill training at a random step, resume on a different GPU count, and check the sample-stream hash matches
  • Read amplification check: measure bytes read per GPU on real data. Lane slices simulate at 1.01–1.25×. Add a per-node cache only if it's needed. Measured on FineWeb-Edu lengths: at the bound 1 + (world − 1)/W (1.013× at W = 512 on 8 GPUs), so no cache (design §6)
  • Benchmarks: publish a comparison table against Mosaic and HF (Benchmarks)
  • Release: build wheels in CI and publish to PyPI
    • wheels for Linux, macOS and Windows and an sdist, each tested on its own OS, published by a v* tag (.github/workflows/release.yml)
    • publish 0.1.0 to PyPI
  • Stretch: in-loader tokenization

Known limits

  • One Loader per GPU process, with num_workers=0 in PyTorch: the parallelism is in Rust, and forking a process with a running runtime is unsafe.
  • Read amplification is about 1 + (GPUs − 1)/W: set the window W to many times your GPU count (for example W = 512 costs 1.4 % on 8 GPUs).
  • CPU per token and the time to the first batch after a resume are still behind Hugging Face datasets' memory-mapped Arrow copy; both are the next work on speed.
  • Input is pre-tokenized text only; tokenization, images and dataset mixing are out of scope for 0.1.

Development

pip install maturin
maturin develop --release        # build the extension into the active virtualenv
cargo test && python -m pytest plitzer-py/tests

CLAUDE.md lists every check that CI runs. A release is a v* tag: CI builds the wheels and the sdist, tests each wheel on its own OS, and publishes them to PyPI (CHANGELOG.md).

License

Licensed under either MIT or Apache-2.0, at your option.

Metadata

Release files for plitzer 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 plitzer 0.1.0
File Size Uploaded Provenance Actions
plitzer-0.1.0.tar.gz 181.6 kB With provenance Details for plitzer-0.1.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for plitzer 0.1.0
File Actions
plitzer-0.1.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details for plitzer-0.1.0-cp311-abi3-win_amd64.whl
plitzer-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl CPython 3.11 abi3 Linux glibc 2.28+ x86-64 Details for plitzer-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl
plitzer-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl CPython 3.11 abi3 Linux glibc 2.28+ ARM64 Details for plitzer-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl
plitzer-0.1.0-cp311-abi3-macosx_10_12_universal2.macosx_10_12_x86_64.macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 10.12+ x86-64, macOS 11.0+ ARM64, macOS 10.12+ universal2 (ARM64, x86-64) Details for plitzer-0.1.0-cp311-abi3-macosx_10_12_universal2.macosx_10_12_x86_64.macosx_11_0_arm64.whl

Total release size: 34.7 MB

Release files / plitzer-0.1.0.tar.gz

Download URL plitzer-0.1.0.tar.gz
Size 181.6 kB
Tags Source
SHA-256 checksum
How to use checksums
0bb535836704ffb98b475f28dc8e6a860f96c73d02d37b1c4f25d7585f0080b9
BLAKE2b-256 checksum
How to use checksums
f94bd4f65ed68ccb4a2e4fb17ce2cef48d84e116531755acab1bd9cf87cc78c3
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 Nov 11, 2026.

Transparency log

Release files / plitzer-0.1.0-cp311-abi3-win_amd64.whl

Download URL plitzer-0.1.0-cp311-abi3-win_amd64.whl
Size 6.3 MB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
be75a489d04afe7b31add9ca3d4ddf89771f6bec163c05d8eb97540ba4d17a4d
BLAKE2b-256 checksum
How to use checksums
78e8907ad0afe6b3c8addb775bd1b63ce07123eaa9c4b29850d537f25bfbd98b
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 Nov 11, 2026.

Transparency log

Release files / plitzer-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl

Download URL plitzer-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl
Size 7.5 MB
Tags CPython 3.11 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
29dbedc5500e23a463967a4f7d596e0251864395fe02d96a4140eceeb13b9367
BLAKE2b-256 checksum
How to use checksums
77f03843efa4aa5d52a76176dc7b22cd2f69b7a359f77894904fadb4e054a6f7
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 Nov 11, 2026.

Transparency log

Release files / plitzer-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl

Download URL plitzer-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl
Size 7.5 MB
Tags CPython 3.11 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
aa4007401baa0e6bc07e32adf98d2c08eb6735aa0c65cc396642cb686903f2db
BLAKE2b-256 checksum
How to use checksums
2933666d2a6de319aa1bcdc3b09d8c3ad047ee85cf8907e1c25abbf4aa2dc24c
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 Nov 11, 2026.

Transparency log

Release files / plitzer-0.1.0-cp311-abi3-macosx_10_12_universal2.macosx_10_12_x86_64.macosx_11_0_arm64.whl

Download URL plitzer-0.1.0-cp311-abi3-macosx_10_12_universal2.macosx_10_12_x86_64.macosx_11_0_arm64.whl
Size 13.1 MB
Tags CPython 3.11 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c5dc494a851cdd4e73a1d46b212296c03fc8882ef2fde36b4ac1c177a11a7ba2
BLAKE2b-256 checksum
How to use checksums
8a99714614a6f74863156df1f09aae076181a61c845eea5ea6ce99101ab8b58a
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 Nov 11, 2026.

Transparency log

Security for plitzer 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.

Full provenance

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

Select from 5 files

Attestation for plitzer-0.1.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 Nov 11, 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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

5 release files Full provenance

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