Skip to main content

Sakura: SOTA training services for PyTorch DDP / Lightning / HuggingFace Trainer.

Project description

Sakura

SOTA training services for PyTorch DDP / Lightning / HuggingFace Trainer. Async eval, async checkpoint, mixed precision, torch.compile, ZeRO-1, all installable on a single runtime, all driving a Rust-backed QUIC transport.

InstallQuickstartArchitectureServicesAdaptersDispatchersMigrating from v0.1.x


What is Sakura?

Sakura v1.0 is a standard library that sits on top of every PyTorch frontend (torch.distributed.DistributedDataParallel, lightning.Trainer, transformers.Trainer) and accelerates training via a small, explicit set of installable services:

  • Telemetry — JSON-line event sink
  • MixedPrecision — autocast policies + GradScaler for fp16
  • ActivationCheckpoint — selective torch.utils.checkpoint wrapping
  • Compiletorch.compile with on-disk cache
  • ZeRO1 — optimizer-state sharding
  • AsyncEval — eval at epoch end, dispatched off the training thread
  • AsyncCheckpoint — state-dict writes, dispatched off the training thread

Async services dispatch work to a sakura-worker subprocess over QUIC (loopback or LAN/WAN). The transport is a Rust crate (sakura-wire) exposed to Python via PyO3. Process isolation means the GIL never contends between training and eval/checkpoint work — a real constraint that thread-pool-based async patterns hit head-on.

Three framework adapters translate framework hooks into runtime events:

  • LightningAdapter — a lightning.Callback
  • HFAdapter — a transformers.TrainerCallback
  • DDPAdapter — explicit hooks for raw torch.distributed loops

You install services on a SakuraRuntime, attach an adapter to your training loop, run as usual.

Install

pip install sakura-ml
# or with framework integrations:
pip install 'sakura-ml[lightning,huggingface]'

From source:

git clone https://github.com/zakuro-ai/sakura && cd sakura
uv pip install maturin
maturin develop --release

Wheel packaging is being finalized — until then, the from-source path is the recommended install.

Quickstart

Lightning

import lightning as L
from sakura import SakuraRuntime
from sakura.adapters import LightningAdapter
from sakura.services import MixedPrecision, Compile, AsyncEval, AsyncCheckpoint
from sakura.dispatch import InThreadDispatcher  # or LocalDispatcher() to spawn a worker

with SakuraRuntime() as rt:
    rt.install(MixedPrecision(dtype="bf16"))
    rt.install(Compile(mode="reduce-overhead"))
    rt.install(AsyncEval(
        eval_fn=lambda epoch, payload: {"val_loss": evaluate(model, val_loader)},
        eval_payload={},
        dispatcher=InThreadDispatcher(),
    ))
    rt.install(AsyncCheckpoint(
        dir="ckpt/", every="best", metric="val_loss",
        dispatcher=InThreadDispatcher(),
        state_provider=lambda: {k: v.cpu() for k, v in model.state_dict().items()},
    ))

    trainer = L.Trainer(
        max_epochs=10,
        accelerator="auto",
        callbacks=[LightningAdapter(rt)],
    )
    trainer.fit(model, train_loader)

HuggingFace Trainer

from transformers import Trainer
from sakura import SakuraRuntime
from sakura.adapters import HFAdapter
from sakura.services import MixedPrecision, AsyncEval

with SakuraRuntime() as rt:
    rt.install(MixedPrecision(dtype="bf16"))
    rt.install(AsyncEval(eval_fn=eval_fn, eval_payload=val_payload,
                          dispatcher=InThreadDispatcher()))
    trainer = Trainer(model=model, args=hf_args, train_dataset=train_ds,
                      callbacks=[HFAdapter(rt)])
    trainer.train()

Raw PyTorch DDP

import torch.distributed as dist
from sakura import SakuraRuntime
from sakura.adapters import DDPAdapter
from sakura.services import ZeRO1, AsyncEval

with SakuraRuntime() as rt:
    rt.install(ZeRO1())
    rt.install(AsyncEval(eval_fn=eval_fn, eval_payload=val_payload,
                          dispatcher=InThreadDispatcher()))

    adapter = DDPAdapter(rt, rank=dist.get_rank(), world_size=dist.get_world_size())
    adapter.on_train_begin(model, optimizer, train_loader)
    for epoch in range(num_epochs):
        adapter.on_epoch_begin(epoch)
        for step, batch in enumerate(train_loader):
            adapter.on_train_step_begin(model, batch, step)
            loss = train_one_step(model, batch, optimizer)
            adapter.on_optimizer_step(optimizer)
        adapter.on_epoch_end(epoch, model, optimizer, metrics={"train_loss": loss})
    adapter.on_train_end(model)

Out-of-process worker (auto-spawned)

LocalDispatcher auto-spawns a sakura-worker subprocess on first dispatch. The eval runs in a separate Python interpreter — the GIL never contends with the training loop:

from sakura.dispatch import LocalDispatcher

dispatcher = LocalDispatcher()  # spawns localhost worker over QUIC
rt.install(AsyncEval(eval_fn=eval_fn, eval_payload=val_payload, dispatcher=dispatcher))

To target an existing worker on another host:

from sakura.dispatch import RemoteDispatcher
dispatcher = RemoteDispatcher(uri="quic://eval-host:4433", cert_der=cert_bytes)

Architecture

┌─── Training process (Python, GIL) ──────────────────────┐
│  framework loop (Lightning / HF / raw DDP)              │
│        │ hook                                           │
│        ▼                                                │
│  Adapter — translates hooks → typed events              │
│        │                                                │
│        ▼                                                │
│  SakuraRuntime — event bus + service registry           │
│        │                                                │
│        ├─→ in-process services (MixedPrecision, …)      │
│        └─→ dispatching services (AsyncEval, AsyncCkpt)  │
│                  │                                      │
│                  ▼                                      │
│            Dispatcher (Local | Remote | InThread)       │
│                  │ PyO3 → sakura-wire (Rust)            │
│                  ▼ QUIC                                 │
└──────────────────│──────────────────────────────────────┘
                   │
┌──────────────────▼──────────────────────────────────────┐
│  sakura-worker subprocess (Python, separate GIL)        │
│      QUIC server → HandlerRegistry → user callable      │
└─────────────────────────────────────────────────────────┘

Five execution states cover every dispatching combination: in-thread (synchronous, for tests), in-process (single Python proc), localhost subprocess (default), remote subprocess (cluster), Zakuro-backed (existing infra). A typed event bus (OnTrainBegin, OnEpochEnd, etc.) carries rank and world_size so DDP-aware services branch on event.rank without each adapter doing the bookkeeping.

Services

Service Priority Hooks consumed What it does
Telemetry 0 every event JSON record sink (callable / file / stream)
MixedPrecision 10 train_begin, optimizer_step wraps forward in torch.autocast; GradScaler for fp16
ActivationCheckpoint 15 train_begin wraps matching submodules with torch.utils.checkpoint
Compile 20 train_begin torch.compile with on-disk cache
ZeRO1 30 train_begin, optimizer_step optimizer-state sharding (single-rank passthrough; multi-rank in progress)
AsyncEval 80 epoch_end dispatch eval to worker; lazy future drain
AsyncCheckpoint 85 epoch_end dispatch state-dict write; modes: epoch / N / best

Lower priority runs earlier. Service exceptions are isolated — one service crashing emits an OnError event but doesn't block the others.

Adapters

Adapter Type Use case
LightningAdapter lightning.Callback Drop-in for lightning.Trainer
HFAdapter transformers.TrainerCallback Drop-in for transformers.Trainer (>=4.38)
DDPAdapter explicit hooks Raw PyTorch DDP loops

Dispatchers

Dispatcher URI When
InThreadDispatcher Tests / debug; runs synchronously
LocalDispatcher auto Default; auto-spawns localhost sakura-worker
RemoteDispatcher quic://host:port Existing remote worker daemon
ZakuroDispatcher Wraps zakuro.Compute for users with existing Zakuro infra

Migrating from v0.1.x

v0.1.x submodules (sakura.lightning.SakuraTrainer, sakura.huggingface.SakuraHFCallback, sakura.ddp.DDPAsyncEvalCallback, sakura.tensorflow.*, sakura.ml.*) have been removed at v1.0.

Users on v0.1.x should pin sakura-ml<1.0 if they're not migrating. To migrate, see docs/migration-from-0.1.md.

Development

git clone https://github.com/zakuro-ai/sakura && cd sakura
uv venv && source .venv/bin/activate
uv pip install maturin pytest cloudpickle numpy torch lightning transformers
maturin develop --release
pytest tests/

Rust workspace: crates/sakura-wire/ — codec + protocol + QUIC transport + PyO3 bindings.

cargo test --workspace
cargo bench -p sakura-wire

License

BSD-3-Clause.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sakura_ml-1.0.0a1.tar.gz (67.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

sakura_ml-1.0.0a1-cp310-abi3-win_amd64.whl (1.6 MB view details)

Uploaded CPython 3.10+Windows x86-64

sakura_ml-1.0.0a1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

sakura_ml-1.0.0a1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.6 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

sakura_ml-1.0.0a1-cp310-abi3-macosx_11_0_arm64.whl (1.5 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file sakura_ml-1.0.0a1.tar.gz.

File metadata

  • Download URL: sakura_ml-1.0.0a1.tar.gz
  • Upload date:
  • Size: 67.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for sakura_ml-1.0.0a1.tar.gz
Algorithm Hash digest
SHA256 cc0dd9007441423b5c299a667eb34eec7eea45fb1a9835d9269ee90597499d87
MD5 9bc01d7f0677e733106abcd5b00e46b8
BLAKE2b-256 ed8fec8a9b0f6ba27a217a136a213b57a2fe56d9dc8f0ec012c859cda460a327

See more details on using hashes here.

File details

Details for the file sakura_ml-1.0.0a1-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: sakura_ml-1.0.0a1-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.6 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for sakura_ml-1.0.0a1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 5c8880f45438391b31787b6e6cfb7ce7d28055249867284685b95fb319077ada
MD5 465e8f6153edb1a9a0bef3c5c434422f
BLAKE2b-256 7233491b260b68f126e713d71fcf4917440df5c6f7505c80a45deba81e234c80

See more details on using hashes here.

File details

Details for the file sakura_ml-1.0.0a1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sakura_ml-1.0.0a1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 173af9ea96944bb4fa7994878d6411df5009cd02a60e176b8445c57e2e76de75
MD5 059b56543452708c6537c570ca2a5670
BLAKE2b-256 28a36adaf7f5b46b238cd0701e51bd17f16410a5bf748cb75a3fc0da1c33f23a

See more details on using hashes here.

File details

Details for the file sakura_ml-1.0.0a1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for sakura_ml-1.0.0a1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0567fabed0a8e8207601b64a63b405ae05816de67979d6588ff2d8ac85079beb
MD5 a356fb6ccfed16a7017f156e46585b31
BLAKE2b-256 14a832fdab7720e0a1dcf2f28afce4a82ef0a0e646ea2c883b35412c8c134106

See more details on using hashes here.

File details

Details for the file sakura_ml-1.0.0a1-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for sakura_ml-1.0.0a1-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7ff13bf1959c94f5372ff499a2a0a382112b183eeb9f986aa998b5f1ea75df88
MD5 5f7ce51b0ff88a2c71aab9a30622be21
BLAKE2b-256 fa883c76344f9a96f0dba54653e25a4448e50f083cca309e1cb03c08038972ed

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page