Research-grade experiment tracking SDK. Local-first; ships to the Siliconworm dashboard when configured.
Project description
siliconworm — Python SDK
The official client for the Siliconworm
experiment tracker. Drop-in for wandb-style code, but stays local-first:
metrics are always written to ~/.siliconworm/runs/<id>/ and only optionally
shipped to a remote ingest endpoint.
Install
pip install siliconworm # core, zero required deps
pip install "siliconworm[torch]" # adds torch tensor auto-coercion
pip install "siliconworm[numpy]" # adds numpy scalar auto-coercion
Source install:
git clone https://github.com/aryan-shubh/siliconworm
cd siliconworm/sdk/python
pip install -e .
30-second tour
import siliconworm as sw
run = sw.init(
project="viscount-lm",
config={"lr": 3e-4, "batch_size": 512, "optimizer": "muon"},
)
for step, batch in enumerate(loader):
loss = model.step(batch)
run.log({"train_loss": loss, "lr": sched.lr}, step=step)
run.summary["final_acc"] = acc
run.finish()
That's it. No login, no project setup, no dashboard required. The run record
lives at ~/.siliconworm/runs/<id>/:
metrics.jsonl # one JSON object per .log() call
summary.json # final aggregates + run metadata
config.json # hyperparameters as passed to init()
system.json # host, python, git, gpu snapshot
What's captured automatically
On init() the SDK snapshots:
- git — current sha, branch, dirty flag, remote
- python — version, executable, implementation
- host — user, hostname, OS
- process — argv, cwd, pid
- gpu — if
torch.cuda.is_available(), each device's name, compute capability, total memory, CUDA + torch versions
This goes to system.json once at start. Nothing is sent over the network
unless you opt in.
Optional: ship to a Siliconworm server
If SILICONWORM_API_URL is set, every batch is POSTed to:
POST <SILICONWORM_API_URL>/v1/runs # init payload
POST <SILICONWORM_API_URL>/v1/runs/<id>/metrics # ndjson batch
POST <SILICONWORM_API_URL>/v1/runs/<id>/summary # full summary
POST <SILICONWORM_API_URL>/v1/runs/<id>/finish # end-of-run
Auth via SILICONWORM_API_KEY → Authorization: Bearer …. Failures are
swallowed after a couple of retries — the local jsonl is always the source
of truth, so a flaky network never loses a step.
API surface
run = siliconworm.init(
project="…", # required
name=None, # auto-generated "wise-yak-042" if omitted
config={…}, # any JSON-serialisable hyperparameters
tags=[…],
group=None,
notes=None,
job_type=None,
dir=None, # override base output dir
api_url=None, # else read from SILICONWORM_API_URL
api_key=None, # else read from SILICONWORM_API_KEY
)
run.log({"metric": value, …}, step=None) # step auto-increments if None
run.summary["final_acc"] = 0.987 # writes summary.json eagerly
run.finish(exit_code=0)
The bare module also exposes siliconworm.log(...) / siliconworm.finish() that
dispatch to the most recent init() — handy when threading a run object
through your code is awkward.
Tensor / numpy coercion
run.log({"loss": tensor}) does the right thing — 0-d torch tensors become
tensor.item(), vectors become .mean().item(). Same for numpy scalars.
No need to call .item() yourself.
Context manager
with siliconworm.init(project="foo") as run:
for step in range(N):
run.log({"loss": loss}, step=step)
# finish() is called automatically; exceptions are recorded as summary._error.
Examples
examples/quickstart.py— fake training loop, no dependencies beyond the SDKexamples/mnist.py— real MNIST + MLP using torch, same spec as_training/train.pyin the repo
Status
Alpha. The wire protocol may change before 0.2; pin siliconworm==0.1.* if
you depend on it.
Releasing (maintainers)
The build + publish flow is driven by uv and PyPI Trusted Publishing — no API tokens stored anywhere.
One-time setup, on pypi.org/manage/account/publishing:
- PyPI Project Name:
siliconworm - Owner:
aryan-shubh - Repository name:
siliconworm - Workflow filename:
publish-python.yml - Environment name:
pypi(repeat at test.pypi.org with envtestpypi)
Then, for each release:
-
Bump
siliconworm/version.pyand add aCHANGELOG.mdentry. -
Open a PR. CI runs
uv build+twine check --strict+ a smoke test. -
After merge, draft a GitHub release with tag
sdk-python-vX.Y.Z(e.g.sdk-python-v0.1.0). Publishing the release triggers.github/workflows/publish-python.yml, which runs:uv build uv publish # OIDC-authenticated, no token needed
Local dry-runs (uses an API token you set as UV_PUBLISH_TOKEN):
cd sdk/python
uv build
uv publish --index testpypi # → TestPyPI
uv publish # → PyPI (don't do this casually)
You can also dress-rehearse the GitHub flow without touching real PyPI:
Actions tab → Publish Python SDK → Run workflow → target: testpypi.
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file siliconworm-0.1.0.tar.gz.
File metadata
- Download URL: siliconworm-0.1.0.tar.gz
- Upload date:
- Size: 14.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.18 {"installer":{"name":"uv","version":"0.11.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7cdc4d4aaa823d12b37ea1eb12601d4dc375f4f165f708741f613d284390f1e3
|
|
| MD5 |
6ff519e6255718154a3155e8c7b8890c
|
|
| BLAKE2b-256 |
e81edbc2ee581d23c3fb27835774fc8b38ce628f5883fb58d80a112d4e95391a
|
File details
Details for the file siliconworm-0.1.0-py3-none-any.whl.
File metadata
- Download URL: siliconworm-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.18 {"installer":{"name":"uv","version":"0.11.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8c3b4242f69bd5e94f18fc748831fd7133613469cb6fe29f11b6134ee5f13d1
|
|
| MD5 |
060aa348015ab3e98ad85a0534322e69
|
|
| BLAKE2b-256 |
4d0f9994106ff03282fb1c7a7d4fe84bcbb8b56a82526fe6a1f253ce3910d6b6
|