Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Zephyr

Simple data processing library for Marin pipelines. Build lazy dataset pipelines that run on Iris jobs or a local backend.

Quick Start

from zephyr.context import ZephyrContext
from zephyr.dataset import Dataset
from zephyr.readers import load_jsonl

# Read, transform, write
ctx = ZephyrContext(max_workers=100)
pipeline = (
    Dataset.from_files("gs://input/", "**/*.jsonl.gz")
    .flat_map(load_jsonl)
    .filter(lambda x: x["score"] > 0.5)
    .map(lambda x: transform_record(x))
    .write_jsonl("gs://output/data-{shard:05d}-of-{total:05d}.jsonl.gz")
)
ctx.execute(pipeline)

Key Patterns

Dataset Creation:

  • Dataset.from_files(path, pattern) - glob files
  • Dataset.from_list(items) - explicit list

Loading Files

  • .load_{file,parquet,jsonl,vortex} - load rows from a file

Pass include_file_paths=True to add __file_path to each row (or set file_path_column to use another name). Selecting only that column returns the source path for each matching row. Parquet path-only reads skip source data columns unless a filter needs them.

For CPU-heavy local row transforms, enable intra-shard execution on the context:

from zephyr.context import IntraShardExecution, ZephyrContext
from zephyr.runners import SubprocessRunner

ctx = ZephyrContext(
    max_workers=4,
    stage_runner_factory=SubprocessRunner,
    intra_shard_execution=IntraShardExecution.AUTO,
)

The planner inserts Split → Map → Concat around independent row operations. Use this option when row callbacks do not depend on per-shard mutable state. When there are fewer source shards than workers, the planner reads Parquet footers and divides row ranges into up to four tasks per worker, capped at one task per row. It gives larger row ranges more tasks. Existing shards stay intact when they already fill the worker pool, avoiding extra Split and Concat stages. A later reshard to fewer shards can still split existing intermediate chunks. Row maps after group_by stay with the reduce stage and run on each whole output shard. Concat restores each original shard's row order and ID before writes, joins, windows, take_per_shard, and map_shard. Output filenames and shard counts therefore stay the same. The default is OFF.

This adds intermediate writes and reads, without a key shuffle. When an independent map chain ends in write_parquet with an explicit schema, fragments are written as Parquet and the final writer consumes Arrow batches. Other boundaries use the existing pickle chunks. Parquet workers still read overlapping row groups in full, so splitting a large row group increases read work and memory use. Batch-mode Parquet sources retain their original batch boundaries. Opaque loaders and map_shard callbacks are not subdivided internally; a source yielding a single item or chunk may still have only one runnable task. As with explicit resharding, materialized map stages run before a final writer can skip an existing output file.

Transformations:

  • .map(fn) - transform each item
  • .flat_map(fn) - expand items (e.g., load_jsonl)
  • .filter(fn) - filter items by function or expression
  • .select(columna, columnb) - select out the given columns
  • .window(n) - group into batches
  • .reshard(n) - redistribute across n shards

Output:

  • .write_jsonl(pattern) - write JSONL (gzip if .gz)
  • .write_parquet(pattern, schema) - write zstd Parquet with page indexes and at most 256 rows per data page
  • .write_vortex(pattern) - write to a Vortex file

Execution (ZephyrContext):

  • ZephyrContext(max_workers=N) — auto-detects the backend (Iris inside an Iris job, local otherwise) via fray.current_client()
  • ZephyrContext(client=LocalClient()) — explicit local backend (testing)
  • ctx.execute(pipeline) — runs the pipeline; returns a ZephyrExecutionResult(results, counters)
  • ctx.execute(pipeline, name="rlvr-ifeval-review") — prefixes the execution ID shown in logs and the dashboard. Names become lowercase ASCII alphanumerics and dashes, capped at 64 characters. Omitted or empty normalized names keep the timestamp/hash format.

Real Usage

Wikipedia Processing:

from zephyr.context import ZephyrContext
from zephyr.dataset import Dataset
from zephyr.readers import load_jsonl

ctx = ZephyrContext(max_workers=100)
pipeline = (
    Dataset.from_list(files)
    .load_jsonl()
    .map(lambda row: process_record(row, config))
    .filter(lambda x: x is not None)
    .write_jsonl(f"{output}/data-{{shard:05d}}-of-{{total:05d}}.jsonl.gz")
)
ctx.execute(pipeline)

Dataset Sampling:

from zephyr.context import ZephyrContext
from zephyr.dataset import Dataset

ctx = ZephyrContext(max_workers=1000)
pipeline = (
    Dataset.from_files(input_path, "**/*.jsonl.gz")
    .map(lambda path: sample_file(path, weights))
    .write_jsonl(f"{output}/sampled-{{shard:05d}}.jsonl.gz")
)
ctx.execute(pipeline)

Parallel Downloads:

from zephyr.context import ZephyrContext
from zephyr.dataset import Dataset

tasks = [(config, fs, src, dst) for src, dst in file_pairs]
ctx = ZephyrContext(max_workers=32)
pipeline = Dataset.from_list(tasks).map(lambda t: download(*t))
ctx.execute(pipeline)

Installation

# From Marin monorepo
uv sync

# Standalone
cd lib/zephyr
uv pip install -e .

Running Tests

Zephyr tests run against multiple execution backends to ensure correctness across different environments.

All Tests on Both Backends (Default)

uv run pytest lib/zephyr/tests
# Runs all tests on both Local and Iris backends
# Local Iris cluster is started automatically via ClusterManager

Run Specific Backend Only

uv run pytest lib/zephyr/tests -k "local"
uv run pytest lib/zephyr/tests -k "iris"

The Iris cluster is started once per test session and reused across all tests for efficiency.

Design

Zephyr consolidates ad-hoc distributed and Hugging Face dataset processing patterns in Marin into a simple abstraction.

Key Features:

  • Lazy evaluation with operation fusion
  • Disk-based inter-stage data flow for low memory footprint
  • Chunk-by-chunk streaming to minimize memory pressure
  • Distributed execution with bounded parallelism (Iris/local backends)
  • Automatic chunking to prevent large object overhead
  • fsspec integration (GCS, S3, local)
  • Type-safe operation chaining

Shuffle ingestion bounds its input buffer by serialized payload bytes and item count before passing frames to the memory-aware writer. This also applies when each item is itself a batch. A single item must still fit in task memory.

See AGENTS.md for execution internals and source layout.

Metadata

Release files for marin-zephyr 0.2.182.dev38801935455

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

Source distribution (sdist)

Source distribution for marin-zephyr 0.2.182.dev38801935455
File Size Uploaded
marin_zephyr-0.2.182.dev38801935455.tar.gz 123.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for marin-zephyr 0.2.182.dev38801935455
File Interpreter ABI Platform
marin_zephyr-0.2.182.dev38801935455-py3-none-any.whl Python 3 none any Details

Total release size: 259.4 kB

Release files / marin_zephyr-0.2.182.dev38801935455.tar.gz

Download URL marin_zephyr-0.2.182.dev38801935455.tar.gz
Size 123.3 kB
Tags Source
SHA-256 checksum
How to use checksums
1d9d03eb37a568ce1fec61029c21b271d08225da8921122fc35a06fb64394cb6
BLAKE2b-256 checksum
How to use checksums
e2a6bd96d7182e0730074574bd1316dc45a6cfe4e1bf2af1e3fad69e5110a8a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 15, 2026.

Transparency log

Release files / marin_zephyr-0.2.182.dev38801935455-py3-none-any.whl

Download URL marin_zephyr-0.2.182.dev38801935455-py3-none-any.whl
Size 136.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f0d21dc0942259e08aed412246c833ea98681e17704d797293221881ab90726f
BLAKE2b-256 checksum
How to use checksums
3f36e19ae678212af7713aa0dfb4112fd8c08ea5d21042fc5fc19a84fcc62250
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release
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