Files
yolo/README.md
Kunpeng 25fa0c5825 feat: SQLite persistence, non-blocking inference, modular frontend
Backend:
- Persist alert events and robot delivery counters in SQLite (data/app.db,
  YOLO_DB_PATH override); EventStore keeps its interface, DeliveryStatsStore
  uses read/write-through UPSERT; in-memory fallback remains for standalone
  AlertManager use
- Serve /api/detect from a sync endpoint and serialize YOLO inference with a
  lock, so concurrent requests no longer block the event loop
- Unify single-image and session detection: requests without session_id
  share the fixed single-image session and run full frame confirmation
- Store UTC Z-suffixed timestamps for sortable string comparison; close
  executor and database on shutdown via FastAPI lifespan

Frontend:
- Split app.js into ES modules (main.js + modules/{dom,api,ui,charts,store}
  + views/{dashboard,inspection,events,robots,robotCards}), no build step
- Escape all server data interpolated into innerHTML; guard missing
  event.classes; replace lazy element ID list with memoized qs()
- Remove hardcoded fake stats (trend badge, device donut segment)

Docs:
- Rewrite README: accurate weight policy (only trained best.pt committed,
  no Git LFS), SQLite persistence, single-worker note, data asset inventory
- Align models/pretrained/README.md with actual files; add YOLO_DB_PATH to
  .env.example; add persistence unit tests; ruff clean
2026-08-13 16:50:23 +08:00

4.8 KiB

Smoke and Fire YOLO

Ultralytics YOLO training, validation, prediction, and export pipeline for the Smoke-Fire-Detection-YOLO dataset, plus an integrated fire prevention management platform (FastAPI + browser frontend).

Project layout

configs/datasets/smoke_fire.yaml  Dataset configuration
models/pretrained/                Locally cached base weights (not committed)
src/yolo/cli.py                   Command-line entry point
src/yolo/config.py                Training configuration
src/yolo/defaults.py              Project defaults
src/yolo/engine.py                Train, validate, predict, and export
src/yolo/checkpoints.py           Checkpoint discovery and resume support
src/yolo/reporting.py             Training result reporting
backend/                          FastAPI inference API and alerting
frontend/                         Browser management platform (no build step)

Setup

uv sync

Trained deployment weights are committed as regular files under runs/detect/*/weights/best.pt, so the API works right after cloning. Checkpoint files (epoch*.pt, last.pt) and re-downloadable base weights are excluded by .gitignore.

Commands

Fine-tune from the current best YOLO11s checkpoint:

uv run fire-yolo train

Resume from the newest checkpoint:

uv run fire-yolo train --resume

Validate a trained model:

uv run fire-yolo val --weights runs/detect/<run-name>/weights/best.pt

Run inference:

uv run fire-yolo predict --weights runs/detect/<run-name>/weights/best.pt --source path/to/image-or-video

Export a model:

uv run fire-yolo export --weights runs/detect/<run-name>/weights/best.pt --format onnx

Default training settings

  • Model: runs/detect/smoke_fire_yolo11s_v1-4/weights/best.pt
  • Dataset: configs/datasets/smoke_fire.yaml
  • Epochs: 80
  • Image size: 768
  • Batch: 24
  • Workers: 0
  • Optimizer: AdamW
  • Initial learning rate: 0.0002
  • Mosaic/MixUp: disabled
  • Prediction confidence: 0.40
  • Checkpoint interval: every 5 epochs
  • Output: runs/detect

Training writes last.pt, best.pt, periodic checkpoints, and best_point.json to the run directory.

The committed best weights and evaluation evidence are summarized in docs/model_comparison.md. Only trained best.pt files are committed; to make a newly trained model available for deployment, commit its weights/best.pt after the run finishes.

Web Detection Service

After training finishes, install the web dependencies and run the integrated frontend and inference API:

uv sync
uv run uvicorn backend.main:app --host 127.0.0.1 --port 8000

Open http://127.0.0.1:8000 to use the fire prevention management platform. It provides a system overview, local-video inspection, alert event handling, a risk register, robot channel status, and effective model settings. The browser plays selected videos locally and sends sequential JPEG frames to POST /api/detect; requests do not overlap.

Management endpoints include GET /api/dashboard, GET /api/events, PATCH /api/events/{event_id}, and GET /api/robots. Alert events can be marked as pending, acknowledged, or resolved. The robot endpoint reports Enterprise WeChat and Feishu configuration and delivery statistics without exposing webhook credentials. Use POST /api/robots/{channel}/test to send a connection test to a configured group robot.

Events and robot delivery counters are persisted in SQLite (data/app.db by default, override with YOLO_DB_PATH), so they survive service restarts. The event store keeps the most recent 500 events. Run the API with a single uvicorn worker: per-session consecutive-frame state lives in the process.

The local .env file contains optional robot settings. Set WECHAT_WEBHOOK_URL for an Enterprise WeChat group robot, FEISHU_WEBHOOK_URL for a Feishu custom group robot, or both. If Feishu signature verification is enabled, also set FEISHU_SECRET. Alerts require three consecutive positive frames by default and use separate 60-second cooldowns for fire and smoke. ALERT_CONFIRM_FRAMES and ALERT_COOLDOWN_SECONDS override these settings. Without a webhook, video detection still works and the UI reports that notifications are disabled.

Detection requests without a session_id share the fixed single-image session, so the consecutive-frame confirmation also applies to them; reset it with DELETE /api/sessions/single-image.

Data assets

  • data/Smoke-Fire-Detection-YOLO/ — main smoke/fire dataset (train/val/test).
  • data/fire-dataset/ — incremental hard-negative collection (395 train / 87 val images, Pascal VOC XML plus YOLO labels); not yet wired to a training config.
  • runs/audit/ — label audit tooling: scan_missing_labels.py finds unlabeled images that the current model detects, render_missing_label_candidates.py renders them for review.