Monolithic repository for the Pyronear temporal smoke classifier: train it, evaluate it, and serve it behind an API.
The model is a per-tube smoke classifier: a YOLO detector proposes boxes, boxes are linked into temporal tubes (greedy IoU), each tube's frames are cropped to 224×224 patches and scored by a ViT (DINOv2) backbone + transformer head that emits one logit per tube.
How the model works → — illustrated step-by-step guide through the full pipeline, with figures generated from real sequences.
Seven independent packages, each with its own pyproject.toml and tests/.
| Path | Import | Purpose |
|---|---|---|
core/ |
temporal_model.core |
Model, tube building, patch extraction, inference, packaging. |
train/ |
temporal_model.train |
DVC training pipeline. Depends on core. |
eval/ |
temporal_model.eval |
DVC evaluation pipeline (packaged-model protocol metrics). Depends on core. |
api/ |
temporal_model.api |
FastAPI serving layer, shipped as a Docker service. Depends on core. |
benchmark/ |
temporal_model.benchmark |
Latency/throughput/resource benchmark with a per-stage predict() breakdown, runnable across VMs. Depends on core. |
monitor/ |
temporal_model.monitor |
Production decision replay: import scored sequences from alert-api, re-run them through the pinned api+model release, view tubes in the eval viewer. |
triage/ |
temporal_model.triage |
Annotation-backlog triage: pull the pyro-annotator unannotated queue (read-only), score it, split into an unlabel worklist + a local-review viewer set. Depends on core. |
train/eval/api/benchmark depend on core via a uv path source
(temporal-model-core = { path = "../core", editable = true }). core and
train pull in PyTorch / timm / ultralytics, so their first uv sync is large.
make # list all available targets (same as `make help`)
make install # uv sync across all seven packages
make test # pytest across all seven packages
make lint # ruff check across all seven packages + docs/assets/scriptsPer package, cd <pkg> && make install|lint|format|test.
make fetch-model # download the released model.zip from HuggingFace (no creds)
make serve # API + MinIO via docker compose, http://localhost:8000 (GET /health)serve is equivalent to cd api && docker compose up --build and refuses to
start until api/models/model.zip exists, so run make fetch-model first (it
pulls v0.1.0 from the public HuggingFace repo; override with
make fetch-model MODEL_VERSION=x.y.z). The compose stack ships local-dev MinIO
defaults (bucket frames, minioadmin creds); with the model present
/health reports model_loaded: true.
make fetch-model # ensure api/models/model.zip exists
cd benchmark && make install && dvc pull # deps + pyro-annotator store
uv run temporal-benchmark core --model ../api/models/model.zipTimes each stage of predict() (yolo / tubes / crop+IO / vit / trigger) over
the pyro-annotator sequence store and writes a self-describing report under
benchmark/data/08_reporting/<host>-<timestamp>/. Designed to run on different
VMs for comparison — see benchmark/README.md and the scripts/ provision /
push / pull helpers.
cd triage && make install # uv sync (brings dvc[s3])
AWS_PROFILE=pyronear uv run dvc pull # fetch data/02_shards from S3
uv run temporal-triage unpack # tars → loose store + report
( cd ../viewer && npm install ) # first time only
make viewer # browse at localhost:3000triage/ pulls the pyro-annotator's unannotated backlog (read-only), scores it
with the model, and splits it into To Review (worth a human's eyes) and
Unlabel (auto false-positive) buckets, browsable in the viewer. The commands
above are the consumer flow (no annotator credentials, no model, no Docker);
producing new data needs credentials — see triage/README.md.
Ported from the Pyronear vision-rd
research repo's bbox-tube-temporal work:
core/— fromlib/bbox-tube-temporaltrain/andeval/— fromexperiments/temporal-models/bbox-tube-temporal