The happy path
One call, called once per process. Framework hooks do the work.cirron.session root scope,
starts a background flush thread, and registers clean-shutdown handlers.
| Framework | Triggered by | What you get |
|---|---|---|
| Keras | model.fit() | epoch and batch scopes; logged metrics as marks |
| HuggingFace Trainer | trainer.train() | epoch and step scopes; end-of-epoch values as summary marks |
| PyTorch + DataLoader | for batch in loader: | data_load, forward, backward, optimizer_step, implicit step |
Distributed training
Every rank callsci.profile(). The SDK reads RANK / LOCAL_RANK /
WORLD_SIZE from the environment and tags every span with the rank.
The platform merges views at query time.
Custom loops
If your loop doesn’t fit the hook patterns (generator-based iteration, custom samplers, step counters without a DataLoader), wrap the iterables. They’re transparent:ci.epochs(range(20)) yields 0..19
exactly while opening an indexed epoch scope around each iteration.
ci.batches() additionally measures DataLoader stall time (waiting on
data vs. compute) when the iterable is a torch.utils.data.DataLoader.
See ci.epochs / ci.batches.
Scopes and marks
Useci.scope for explicit spans the hooks and
wrappers don’t cover (augmentation, beam search, custom schedulers).
Use ci.mark to attach scalar values to the
innermost open scope.
epoch / batch / forward tree stays intact and your custom
scope slots in at the right level. Max depth: 64.
Framework hooks
Hooks install automatically byci.profile() when the framework is
importable. Each hook is wrapped in a top-level try/except, so a
failing hook logs a warning and training continues.
When multiple frameworks are installed, hooks fire in priority order
transformers > tensorflow > torch. Higher-level frameworks claim
ownership of the semantic scopes (epoch, step) first; lower-level
frameworks yield, so no semantic scope is duplicated.
- PyTorch uses module pre/post hooks, autograd hooks,
optimizer-step hooks, and DataLoader iterator wrapping; gradient
accumulation collapses to a single
stepspan. CUDA timing viatorch.cuda.Eventpairs lands on thegpu_nsattribute. - Keras auto-registers a
CallbackonModel.fit; logged metrics become marks. - HuggingFace auto-registers a
TrainerCallbackonTrainer.__init__; end-of-epoch values are markedkind="summary". - scikit-learn has no auto-hook; wrap the estimator with
ci.wrap.
ci.profile for the full hook table and
per-framework details.
Snapshots
At each detected epoch boundary, the SDK captures per-tensor statistics for every parameter in the model being profiled. Three modes, controlled byci.profile(snapshots=...).
| Mode | Cost per boundary | What’s captured |
|---|---|---|
"stats" | ≤ 50 ms (typical) | {mean, std, min, max, norm, histogram[16]} per tensor |
"sampled" | ≤ 200 ms on sampled steps | Stats + raw tensors for random() < sample_rate epochs |
"full" | unbounded; debug-only | Stats + raw tensors every epoch |
"sampled" and "full" modes, raw tensors are written as
safetensors blobs at ./.cirron/snapshots/<span_id>/weights.safetensors
(and gradients.safetensors when gradients are non-None).
Keras and HuggingFace hooks discover the model from their callback
kwargs. Bare PyTorch loops that don’t use ci.epochs() should
register the model once with ci.watch(model)
before training.
"full" mode is not recommended for models over 100M parameters. At
7B+, even "sampled" is expensive. Drop sample_rate.Output sinks
By defaultci.profile() writes each batch as a JSON file under
./.cirron/spool/. Swap or fan-out via output=:
output="none" inside
a Cirron pipeline still ships traces to the platform over the kernel
event stream. See ci.profile
for the full table.
In-process read-back
ci.trace() returns the current session’s scope
tree without leaving the process, useful in notebooks (cell renders
inline) and for ad-hoc analysis (flat DataFrame for quantiles and
group-bys):
Lifecycle
Theatexit handler registered by ci.profile() flushes and shuts down
on process exit. Reach for the manual helpers only when you need
deterministic behavior in tests or hot-reload scenarios:
Next
Inference guide
@ci.inference, LLM detection, config-driven capture.ci.profile reference
Full signature and parameter table.
ci.trace reference
Read-back formats and filters.