-
Notifications
You must be signed in to change notification settings - Fork 0
production workflows
Phase 6 closes the gap between "works" and "trustworthy in production": a run records how to reproduce itself, checkpoints become searchable, training scales up behind opt-in flags, performance is tracked over time, and logs and metrics become machine-readable. Every addition is opt-in and the default workflow is unchanged.
spikeforge/tracking/ records
what a run needs to be recreated and compared. A
ReproducibilityManifest captures
the dataset, topology and params, encode config, hyperparameters, the resolved
TopologySpec, the library versions, the seed, and the metric history.
config_hash() hashes the
reproducibility-relevant config as canonical JSON (sorted keys, tight
separators), so two runs with identical settings compare equal regardless of
when they ran or what their histories show, and
set_seed() seeds Python, PyTorch, and
every CUDA device.
Reproducibility is stated honestly in the manifest's reproducible block; it
is not claimed to be bit-exact. Guaranteed to reproduce from the manifest
alone: the topology structure and resolved spec, the dataset/encode config and
hyperparameters, the library versions and seed, and the initial parameter
values for the same library build on CPU. Not guaranteed bit-for-bit: CUDA
kernels (cuDNN, parallel reductions), hardware thread scheduling and any float
summation order that follows, and dataset contents if the source files change
between runs. set_seed deliberately leaves the global deterministic flags
alone so seeding never slows the default training path.
The file-based MODEL_DIR registry stays the source of truth, but two
read-only helpers make it searchable and comparable.
search_models(...) filters
checkpoint summaries by dataset, topology, coding, device, minimum accuracy,
and a case-insensitive name substring; each result carries the newest non-null
test accuracy and the stored manifest (or null for a legacy checkpoint).
checkpoint_diff(...) classifies
every metadata key as added, removed, changed, or same and compares the
two manifests' config hashes. list_models and its payload shape are
untouched, so existing callers are unaffected.
The spikeforge-records console script (also verify records ...) exposes both:
spikeforge-records list --dataset mnist --topology conv_net --min-accuracy 90
spikeforge-records diff old_model new_model
spikeforge-records manifest my_modelThe server mirrors this with read-only model_search and model_diff
WebSocket actions (model_search/model_diff replies); a diff without exactly
two names emits the existing error message.
ScaleUpMixin adds four
additive options to TrainConfig. Every default reproduces the previous
behaviour exactly:
| Flag | Default | What it does |
|---|---|---|
amp |
False |
Autocast float16 on CUDA / bfloat16 on CPU, with a CUDA GradScaler; falls back to fp32 when the device rejects the dtype |
grad_checkpoint |
False |
Recomputes each step's activations during the backward pass (smaller activation footprint, more compute) |
bptt_steps |
None |
Detaches the carried neuron state every N steps (truncated BPTT); None keeps full backprop-through-time |
multi_gpu |
False |
DataParallel fan-out when more than one CUDA device is visible |
AMP numerics are close to, but not bit-identical to, fp32.
MultiDeviceManager reports an
honest status (disabled, unavailable: ..., or active: N cuda devices)
instead of failing, and both gradient policies live in the one shared temporal
loop via GradPolicy, so the
forward values are untouched when either is off.
Runs can be recorded and regressions caught over time. A
BenchmarkStore keeps one JSON record
per run under SPIKEFORGE_BENCHMARK_DIR (default <DATA_DIR>/benchmarks), and
run_suite(...) benchmarks a set of
topologies, attaches the library versions plus a timestamp, and saves the
record:
# record a CI-sized suite (the saved run id is <timestamp>-<label>)
python -m spikeforge.benchmark --topology fc_small --topology conv_net \
--steps 8 --repeats 3 --save --label main
# list every stored run, newest first (the list prints each run_id)
python -m spikeforge.benchmark --list
# compare a stored baseline against a fresh run; exit 1 on regression
python -m spikeforge.benchmark --compare <run-id> --threshold 0.1 \
--fail-on-regression
# or diff two stored runs
python -m spikeforge.benchmark --compare <baseline-id> --against <run-id>compare_runs(...) matches records
on (topology, mode) and reports the relative change in ms/step, steps/s,
and peak memory, flagging a regression when a metric moves the wrong way past
the threshold (--fail-on-regression turns that into a non-zero exit, so the
command works as a CI gate). --compare takes a stored run id, not a
label; --list prints the ids. The contract is JSON-able end to end.
spikeforge/observability/
adds two opt-in surfaces, neither enabled unless asked:
-
Structured logging.
configure_logging()attaches one handler to thespikeforgelogger (never the root) andreset_logging()restores the exact prior state. SetSPIKEFORGE_LOG_JSON=1for JSON lines (timestamp,level,event,logger, plus optionalrun_id/config_id/config_hash/fields) orSPIKEFORGE_LOG_LEVEL=DEBUGfor a level. With neither variable set the default human-readable behaviour is untouched, and no entry point callsconfigure_logging()for you. -
Metrics snapshot.
spikeforge.observability.metricsis a process-wideMetricsRegistryof counters, gauges, and timers. The training loop recordstrain.steps,train.encode_seconds,train.forward_seconds, andtrain.backward_seconds; the validation path recordsvalidation.runs,validation.seconds, andvalidation.accuracy(plusvalidation.drifton the NIR interpreter).metrics.snapshot()returns JSON-able data and is surfaced additively as themetricskey of thesystem_statspayload.
Packaging installs a console script per surface, so every headless command has a stable name:
| Script | Equivalent |
|---|---|
spikeforge |
python main.py |
spikeforge-encodings |
python main_encodings.py |
spikeforge-verify |
python -m spikeforge.cli.verify |
spikeforge-records |
python -m spikeforge.cli.verify records |
spikeforge-targets |
python -m spikeforge_targets.cli.target_cli |
spikeforge-hub |
python -m spikeforge_hub.cli |
spikeforge-energy |
python -m spikeforge_targets.energy.cli |
spikeforge-benchmark |
python -m spikeforge.benchmark |
Two opt-in Compose profiles (cpu, gpu) select
explicit CPU-only / CUDA builds of the same service without changing the
default docker compose up --build (CUDA image, dashboard on port 8877, host
GPU reserved). Only one profile can own port 8877 at a time; see the
Docker profiles subsection in Usage.
- Home
- Architecture
- Backend Execution
- Benchmarks
- Dashboard
- Development
- Event Datasets
- Event Runtime And Energy
- Features
- Implications And Boundaries
- Interop Foldins
- Interpreter Spine
- Introspection
- Model Deployment
- Model Hub
- Notes
- Operational Maturity
- Production Workflows
- Project Layout
- Quickstart
- Requirements
- Sequence Primitives
- Streaming Timeseries
- Targets And Interop
- Usage
- Arch 0001 Adr Repo Topology
- Arch 0001 Core Boundary
- Arch 0001 Decision Metrics
- Arch 0001 Migration Plan
- Arch 0001 Packaging Versioning
- Arch 0001 Protocol Contract
- Arch 0001 Risk Register
- Arch 0001 Target Topology
- Backend Execution Plan
- Ecosystem Listings
- Ecosystem Roadmap
- Event Runtime Plan
- Hub Expansion Plan
- Plans
- Interop Foldins Plan
- Interpreter Spine Plan
- Memory System Research
- Model Hub Plan
- Operations Plan
- Production Toolkit Plan
- Production Use Cases
- Professional Roadmap
- Repo Topology Plan
- Sequence Primitives Plan
- Use Case Audio Keyword Spotting
- Use Case Biosignal Medical Monitoring
- Use Case Computational Neuroscience
- Use Case Edge Power Budgets
- Use Case Event Camera Vision
- Use Case Intrusion Anomaly Detection
- Use Case Low Latency Sensor Stream
- Use Case Rl Control Robotics
- Use Case Spiking Transformers
- Use Case Streaming Timeseries