A PyTorch framework for continual learning that automatically detects concept drift in data streams and adapts models through JVP regularized retraining.
The pipeline runs on a changing data stream and loops through these stages:
- Evaluate the current model on stream batches.
- Aggregate monitored metrics at a configured interval.
- Run a drift detector on the aggregated metric.
- If drift is detected, pause monitoring and run a continual-learning update loop.
- Resume monitoring on the updated model and continue until stream limits are reached.
Core modules:
src/main.py: entry pointsrc/apeiron/config/configuration.py: TOML/env/CLI config assemblysrc/apeiron/driver/continuous_monitor.py: monitoring + drift loopsrc/apeiron/training/continuous_trainer.py: CL training loopsrc/apeiron/training/updater/: CL update strategiessrc/apeiron/drift_detection/: detectors and detector factoryexamples/: standalone example projects (each declaresapeironas a dependency)
# pyproject.toml
[tool.poetry.dependencies]
apeiron = "^0.1.0" # once published to PyPI
# Or as a path dependency during development
apeiron = { path = "../apeiron/", develop = true }from apeiron import BaseModelHarness, ContinuousMonitor, build_config
from apeiron.drift_detection import ADWINDetector
from apeiron.training.updater import BaseUpdaterRequires Python >=3.13,<3.14 and Poetry.
poetry installFrom the project root:
poetry run python -m src.main --config examples/mnist/mnist.toml
poetry run python -m src.main --config examples/cifar/cifar10_vit.toml
poetry run python -m src.main --config examples/imagenet/imagenet_vit.toml # requires ImageNet data at data.pathCurrently, we support two metrics logging backends: Weights & Biases (WandB) and MLflow. You can configure the desired backend in the config file's logging section. To disable logging, you can set the logging section to none to disable logging. Alternatively, you can set the logging choice via command line arguments, for example:
poetry run python -m src.main --config examples/mnist/mnist.toml --set logging.backend=mlflow --set logging.experiment_name="My Experiment"
# To view results for MLflow, run `mlflow ui` in another terminal and navigate to http://localhost:5000Currently the mnist example sets the logging to wandb in the toml config file. The other examples do not set any metric for the logging backend, which defaults to wandb.
Primary sections in config TOML:
[model][data][train][drift_detection][continual_learning](optional but recommended)[visualization](optional)
Top-level fields commonly used:
seeddevicemulti_gpuverbosity
Override precedence:
- Base TOML (
--config) - Environment overrides prefixed with
APP_ - CLI overrides via repeated
--set key=value
Example override:
poetry run python -m src.main \
--config examples/mnist/mnist.toml \
--set drift_detection.detector_name=\"KSWINDetector\" \
--set train.max_iter=200This repo ships task-oriented agent skills that walk an AI coding agent through the common Apeiron workflows. The same four skills are maintained for both tools:
- Claude Code —
.claude/skills/<name>/SKILL.md - Codex —
.codex/skills/<name>/SKILL.md
| Skill | What it does |
|---|---|
install-apeiron |
Add Apeiron as a dependency to another project (path/git), verify import apeiron, pick CPU vs CUDA PyTorch. |
explore-examples |
Run a bundled example (MNIST/CIFAR) to see drift detection + CL in action; picks a config and reports the metrics CSV. |
custom-experiment |
Scaffold a harness, data utils, and TOML for your own dataset/model, register it in the example factory, smoke-test, and run. |
integrate-apeiron |
Add Apeiron's drift detection / CL to an existing training loop; inspects your repo and writes the lightest adapter that fits. |
Claude Code — the skills are exposed as slash commands. Type / and the
skill name, e.g.:
/explore-examples
/install-apeiron ../my-project
You can also just describe the task in plain language ("add apeiron to my training loop") and the matching skill triggers from its description.
Codex — the equivalent skills live under .codex/skills/. Invoke a skill by
name or describe the task; Codex selects the skill whose description matches your
request. The skills are tool-agnostic in intent — only the file format differs
between the two trees.
Keep the two trees in sync: a change to a workflow should be reflected in both
.claude/skills/<name>/SKILL.mdand.codex/skills/<name>/SKILL.md.
Detailed docs are in docs/:
docs/README.mddocs/model_harness.mddocs/drift_detectors.mddocs/continuous_learning.md
poetry run pytest
poetry run ruff check .
poetry run mypy .- Builds a
Configfrom the TOML file,APP_environment variables, and--setCLI overrides (src/apeiron/config/configuration.py). - Configures the logging backend and console logger (
src/apeiron/logger/), before constructing the harness so a harness that logs from__init__cannot pin the config. - Selects a concrete
BaseModelHarnessfromcfg.data.nameviaexamples/utils.py:get_example. - Runs
ContinuousMonitor(src/apeiron/driver/continuous_monitor.py), which evaluates streaming batches and calls the drift detector everydetection_intervalbatches. - On drift, dispatches
ContinuousTrainer(src/apeiron/training/continuous_trainer.py) with the updater named by[continual_learning] update_mode.
See docs/architecture.md for the full pipeline, including the detection-only (src/drift_only.py) and adaptation-only (src/cl_only.py) entry points.
- Change the CL loop's outer/inner iteration counts and learning rate through the
[continual_learning]and[train]config sections. - Swap the adaptation strategy with
[continual_learning] update_mode(base,jvp_reg,ewc_online,kfac_online,none). - Tune detection sensitivity with
[drift_detection] detector_nameand its per-detector parameters — seedocs/drift_detectors.md. - Update batch size and worker count with
[train] batch_sizeand[train] num_workers.
The console logger reports per-stage metrics (eval, drift, cl). When [visualization] input is set, the run also writes a metrics CSV at that path for external plotting.
Platform-specific deployment guides: