# SutraAI — 30-Day Plan (v4: Notebook-First on Jetson)

**Project:** SutraAI, a no-code, on-prem edge AI platform (Edge Impulse-style). Users upload data, train, and download models for ESP32, Silicon Labs, Jetson or a Cloud API.

**v4 rule:**

| Phase | Days | What |
|---|---|---|
| **A** | 1–21 | **Build and validate the entire ML flow in Jupyter notebooks on the Jetson Orin NX 16GB (JetPack 6.2.1, CUDA 12.6.68).** No APIs, no web UI. |
| **B** | 22–30 | Only after the Day 21 adoption gate passes: move the proven code into a Python package, then a **minimal FastAPI + Next.js** slice |
| — | Month 2+ | Full web platform, SOC API, chip SDKs |

**For a beginner in AI:** every day has a clear notebook, a "done when" check, and a course slot. The **how** (commands, code, explanations) is in **`SutraAI_Jetson_Beginner_Guide.md`**. This file is the **when**.

**Calendar:** Day 1 = Mon 26 Oct 2026 → Day 30 = Tue 24 Nov 2026 · Sundays are review and buffer days

**Daily rhythm (about 6 h):** 90 min course → 4 h notebook → 30 min `BUILDLOG.md`

---

## 0. What Changed in v4

| v3 | v4 (this plan) |
|---|---|
| Name: (earlier working name) | **SutraAI** |
| Week 1 scripts → Week 2 FastAPI → Week 3 Next.js | **Weeks 1–3: Jupyter notebooks only**, on the Jetson, step by step for a beginner |
| SOC API, Studio UI, public pages in Month 1 | **Moved to Month 2.** The device flow is still proven in Month 1 with a **notebook device simulator** (no API). |
| Cloud training workers | Training runs **on the Jetson** in notebooks. Cloud workers come in Month 2. |
| — | Jetson setup, CUDA libraries, JupyterLab, NVIDIA model tests, and a course list (in the beginner guide) |
| — | **Adoption gate on Day 21**: no web code until it passes |

---

## 1. What We Must Reproduce: 4 Reference Model Types

| Ref | Edge Impulse example | Our template | Data | Pipeline | Notebooks |
|---|---|---|---|---|---|
| R1 | Bird sound (#16060) | **T1 Bird Sound** | Audio 16 kHz | MFCC → 1D-CNN | NB30–NB32 |
| R2 | Driver drowsiness (#510570) | **T2 Driver Drowsiness** | Images + boxes | Centroid object detection | NB40–NB42 |
| R3 | Pneumonia X-ray (#348027) | **T3 Chest X-ray** (research only) · **T5 Defect QC** | Images | Transfer-learning classifier | NB10–NB12 |
| R4 | Fall detection Transformer (#208622) | **T4 Fall Detection** · **T6 Vibration** | Accelerometer 50 Hz | Raw → 1D-CNN / tiny Transformer | NB20–NB21 |

In Weeks 1–3 we prove one of each type on **our own data**: T5 (images), T4 or T6 (sensor), T1 (audio), T2 (detection). T3 uses the same code as T5 and is added later.

---

## 2. The Core Idea: One Pipeline, Driven by `pipeline.yaml`

Every project = **Input → Processing (DSP) → Learning → Export**. In Weeks 1–3 the notebooks build this engine piece by piece. In Week 4 it becomes the `ml_core` package the API calls.

```yaml
# configs/audio.yaml — R1 Bird sound
input:      { type: timeseries, axes: [audio], frequency_hz: 16000, window_ms: 1000, stride_ms: 500 }
processing: { type: mfcc, num_coefficients: 13, frame_length_ms: 20, frame_stride_ms: 20, num_filters: 32, fft_length: 512 }
learning:   { type: classifier, arch: conv1d, epochs: 100, lr: 0.005 }
export:     [onnx, tflite_int8, c_array]
---
# configs/detect.yaml — R2 Driver drowsiness
input:      { type: image, width: 96, height: 96, color: grayscale }
processing: { type: image, normalize: true }
learning:   { type: object_detection, arch: centroid_mobilenetv2_050, epochs: 60 }
export:     [onnx, tflite_int8, tensorrt]
---
# configs/image.yaml — T5 Defect QC / R3 X-ray
input:      { type: image, width: 96, height: 96, color: rgb }
processing: { type: image, normalize: true }
learning:   { type: transfer_learning_image, arch: mobilenetv2_050, epochs: 30 }
export:     [onnx, tflite_int8, c_array, tensorrt]
---
# configs/sensor.yaml — R4 Fall detection
input:      { type: timeseries, axes: [accX, accY, accZ], frequency_hz: 50, window_ms: 4000, stride_ms: 1000 }
processing: { type: raw, scale: 1.0 }
learning:   { type: classifier, arch: transformer_tiny, d_model: 32, heads: 2, layers: 2, epochs: 80, fallback: conv1d }
export:     [onnx, tflite_int8, c_array]
```

**Centroid detector** (NB41): small enough for MCUs, and it converts cleanly to int8.

```python
import timm, torch.nn as nn
class CentroidDetector(nn.Module):
    def __init__(self, n_classes: int):
        super().__init__()
        self.backbone = timm.create_model("mobilenetv2_050", pretrained=True,
                                          features_only=True, out_indices=(2,))   # stride 8
        ch = self.backbone.feature_info.channels()[-1]
        self.head = nn.Sequential(nn.Conv2d(ch, 32, 1), nn.ReLU(), nn.Conv2d(32, n_classes + 1, 1))
    def forward(self, x):
        return self.head(self.backbone(x)[0])       # [B, classes+1, H/8, W/8]; +1 = background
# Target: the cell holding each box centre = class id, all other cells = background. Metric: centroid F1.
```

---

## PHASE A: Notebooks on the Jetson (Days 1–21)

### WEEK 1 (26 Oct – 1 Nov): Jetson, CUDA, and Your First Model End to End

| Day | Notebook / task | ✅ Done when | Course slot (90 min) |
|---|---|---|---|
| **1 (Mon)** | **Jetson setup** (guide §2–3): check the JetPack version, NVMe, MAXN SUPER, headless, 16 GB swap, jtop, SSH | The jtop screen is healthy; you've noted your JetPack/CUDA versions in BUILDLOG | NVIDIA DLI "Getting Started With AI on Jetson Nano" (start) |
| **2 (Tue)** | **CUDA + Python + Jupyter** (guide §4–5): venv, Jetson PyTorch wheel, ONNX Runtime GPU, JupyterLab over an SSH tunnel. **NB00** env check, **NB01** GPU hello | `torch.cuda.is_available()` = True; the GPU beats the CPU on a matmul; TensorRT importable | DLI "An Even Easier Introduction to CUDA" |
| **3 (Wed)** | **NB02 ML basics** (FashionMNIST subset): train/val/test split, epochs, loss curves, overfit on purpose, then fix it | You can explain overfitting from your own plot | ZTM PyTorch: fundamentals + workflow |
| **4 (Thu)** | **NB10 image dataset** (fabric QC: `clean` / `stain` / `hole`, 60 phone photos per class in 4 light × background blocks; or 3 part types; clean splits) → **NB11** first transfer-learning run | `metrics.json` saved; test accuracy recorded | ZTM PyTorch: classification + computer vision |
| **5 (Fri)** | **NB11** continued: augmentation, confusion matrix, look at mistakes, seeds. Move helpers into `sutra_core/data.py` and `train.py` | Test accuracy ≥ 85%; Restart & Run All reproduces it within ±1% | ZTM PyTorch: custom datasets |
| **6 (Sat)** | **NB12 export + validate:** ONNX (parity check), TensorRT engine (latency), TFLite int8 (accuracy check), C array | int8 drop < 3 points; TensorRT latency recorded | TensorRT/ONNX course (export sections) |
| **7 (Sun)** | **Week 1 review:** clean the notebooks, update BUILDLOG, push to git | Image path works from photo to `.tflite` + `.engine` | Catch up |

### WEEK 2 (2 – 8 Nov): Sensor and Audio Pipelines (DSP You Own)

| Day | Notebook / task | ✅ Done when | Course slot |
|---|---|---|---|
| **8 (Mon)** | **NB20 sensor data:** record falls / daily activity (or fan vibration) with the phyphox app → resample to 50 Hz → plot → windows → split by recording | Clear per-class plots; no recording appears in both train and test | ZTM PyTorch: transfer learning |
| **9 (Tue)** | **NB21** 1D-CNN on raw windows | Test accuracy recorded; confusion matrix | ZTM PyTorch (continue) |
| **10 (Wed)** | **NB21** tiny Transformer vs 1D-CNN, same splits → export both to int8 → check TFLite op support | Comparison table; official model chosen (Transformer if it converts, else CNN) | Read: attention basics (any short explainer) |
| **11 (Thu)** | **NB30 audio data** (16 kHz mono clips + noise class) → **NB31 MFCC from scratch** (plot every step; save golden vectors) | MFCC shape (50, 13) per second; correlates with librosa; golden vectors saved | The Sound of AI (YouTube): spectrograms + MFCC |
| **12 (Fri)** | **NB32 audio training:** 1D-CNN on MFCC, noise mixing + time-shift augmentation → int8 export + check | Test accuracy ≥ 80% on your clips; int8 drop < 3 points | The Sound of AI (continue) |
| **13 (Sat)** | **`pipeline.yaml` + NB90 v0:** write `image.yaml`, `sensor.yaml`, `audio.yaml`; NB90 runs any of them end to end through `sutra_core` | All 3 configs run from a clean kernel with no hand edits | — |
| **14 (Sun)** | **Week 2 review** | Three of the four model types work | Catch up |

### WEEK 3 (9 – 15 Nov): Detection, Profiling, Device Simulator, NVIDIA Models, Adoption Gate

| Day | Notebook / task | ✅ Done when | Course slot |
|---|---|---|---|
| **15 (Mon)** | **NB40 detection data:** webcam images (with consent) → label boxes in Label Studio → export YOLO format | ≥ 200 labelled images; ≥ 100 boxes per class | TensorRT/ONNX course |
| **16 (Tue)** | **NB41** centroid detector: targets from boxes, weighted loss, F1, overlay images | F1 ≥ 0.75 per class; overlays look right | — |
| **17 (Wed)** | **NB42** detection export (ONNX → TensorRT, TFLite int8) + **NB50 profiler** (flash / RAM / latency table for every model × target) | int8 F1 drop < 0.05; `reports/profile.md` saved | — |
| **18 (Thu)** | **NB51 device simulator (no API):** manifest + sha256 → LiteRT int8 inference → telemetry → review list → retrain → "OTA" v1 → v2 | v2 beats v1; corrupted file is rejected; telemetry JSON saved | — |
| **19 (Fri)** | **NB60 Nemotron 3 Nano 4B** (build llama.cpp with CUDA arch 87, run llama-server) as the Training Advisor over `metrics.json` + **NB61 RAG basics** (embed your notes, cited answers, 10-question test) | Advice uses only real numbers; RAG hit@4 ≥ 8/10; tokens/s + RAM noted | Ed Donner LLM Engineering: RAG section |
| **20 (Sat)** | **NB62 NVIDIA vision helpers:** Cosmos Reason 2 2B (check labels / describe images) + NanoOWL (zero-shot boxes to pre-label NB40) | Table of time saved + error rate; decision on auto-labeling for Month 2 | Jetson AI Lab tutorials |
| **21 (Sun)** | **NB90 final: ADOPTION GATE.** All 4 configs (`image`, `sensor`, `audio`, `detect`) run end to end from a clean kernel; tick the checklist in guide §10 | **Every box ticked** → go to Phase B. Otherwise, use Days 22–23 to fix and slide Phase B. | — |

---

## PHASE B: From Notebooks to Code (Days 22–30)

> Only start if the Day 21 gate passed. Phase B adds **no new ML**. It wraps what already works.

### WEEK 4 (16 – 22 Nov): Package → API → Minimal UI

| Day | Task | ✅ Done when | Course slot |
|---|---|---|---|
| **22 (Mon)** | **Refactor `sutra_core` → `packages/ml_core`** (installable with `uv`). CLI: `python -m ml_core.run configs/audio.yaml`. pytest uses the golden vectors + tiny datasets. | CLI reproduces the NB90 numbers; tests pass | FastAPI course (basics, fast) |
| **23 (Tue)** | **FastAPI skeleton:** `POST /projects`, `POST /projects/{id}/dataset` (zip upload), `POST /projects/{id}/train`, `GET /jobs/{id}`, `GET /models/{id}/download?format=` | All endpoints work with curl on the Jetson | FastAPI course |
| **24 (Wed)** | **Job worker** (Celery + Redis, concurrency 1 on the GPU): runs `ml_core`, streams the JSON progress lines over **SSE** `GET /jobs/{id}/events` | Live progress visible with `curl -N`; cancel works | FastAPI course |
| **25 (Thu)** | **Next.js minimal:** pick template (image / sensor / audio / detection) → upload zip → Train (live chart) → Results (metrics + confusion matrix) → Download | One template works end to end in the browser | — |
| **26 (Fri)** | Export menu (all formats) + profiler table in the UI; Nemotron advisor text on the Results page (calls llama-server) | All 4 templates downloadable from the UI | — |
| **27 (Sat)** | **End-to-end demo:** all 4 references through the web slice; record a 5-minute video | Demo video recorded | — |
| **28 (Sun)** | Review and bug fixes | — | — |

### DAYS 29–30 (23 – 24 Nov): Write It Down and Plan Month 2

- `README.md`, `PIPELINE.md` (every notebook step and its numbers), and an API reference.
- Month 2 kickoff list (below). Show the demo to 1–2 people for feedback.

---

## Roadmap After Month 1

| Month | Focus |
|---|---|
| **2: Platform** | Full Studio UI (the `SutraAI UI Flow` canvas): data viewers, labeling, visual pipeline designer, results, deploy. **SOC API v1**: register, ingest, OTA manifest with DSP config, Range download, inference, telemetry. The notebook simulator now talks over HTTP. Public project pages with versions + Clone. Phone-as-device. RAG assistant as a service. Cloud deploy + on-prem `install.sh`. |
| **3: Chips** | C SDKs on SOC API v1: ESP-IDF, Silicon Labs SLC, Renesas RA (FSP), Zephyr. **DSP in C** passing the NB31 golden vectors. Firmware builder + browser flashing. **Measured** profiling on real boards. New blocks: sensor anomaly, regression, bounding-box detector, Sutra Tuner. |
| **4+: Advanced** | Visual anomaly, OCR, counting/tracking, pose, VLM auto-labeling (if NB62 proved it worthwhile), multi-tenant billing |

**SOC API v1 (Month 2) in one line each:**
- `register` → device token
- `ingest` (image / WAV / sensor JSON+HMAC)
- `deployment` manifest (ETag/304, includes the `pipeline` DSP config)
- `artifacts` (HTTP Range)
- `ack`
- `infer`
- `telemetry` → review queue

The notebook simulator (NB51) already does all of these offline, so Month 2 only puts them behind HTTP.

---

## MVP Targets for Month 1 (Goals to Measure)

| Metric | Target |
|---|---|
| Image (T5) test accuracy on your photos | ≥ 85% |
| Audio (T1) test accuracy on your clips | ≥ 80% |
| Sensor (T4/T6) test accuracy | ≥ 85% |
| Detection (T2) centroid F1 | ≥ 0.75 per class |
| int8 vs float32 drop | < 3 points (detection < 0.05 F1) |
| Re-run reproducibility | Within about 1% |
| Nemotron advisor | Uses only real numbers; tokens/s recorded |
| Web slice (Week 4) | Upload → train → download for all 4 templates |

## Risks and Mitigations

| Risk | Mitigation |
|---|---|
| New to AI, so steps take longer than planned | Sundays are buffers; the Day 21 gate may slide Phase B by up to 2 days; never skip a ✅ check |
| 16 GB shared memory still fills up | 16 GB swap, watch jtop, at most one big model next to training (guide §9) |
| JetPack / PyTorch wheel mismatch | Stay on one JetPack; install torch + torchvision together from the Jetson index; verify CUDA after every install |
| onnx2tf 2.x needs Python 3.12+ (the Jetson has 3.10) | Run the TFLite conversion in Google Colab (or a uv Python 3.12 venv); everything else stays on the Jetson |
| Transformer won't convert for MCUs | Auto-fallback to 1D-CNN (`fallback: conv1d`) |
| Notebook code too messy to reuse | Move functions into `sutra_core/*.py` from Week 2; Restart & Run All daily |
| Data licences and privacy | Self-collected data for templates; consent for faces (DPDP Act); X-ray template is research-only |
| YOLO licence (AGPL-3.0) | Our own centroid detector; Apache/BSD/MIT models later |

## Daily Template (`BUILDLOG.md`)

```
## Day N — <date> — <notebook>
Learned:   (course topic + 3 notes in your own words)
Built:     (what works; key cells)
Numbers:   (val/test acc, int8 drop, latency, RAM from jtop)
Blocked:   (error text, what you tried, next try)
Tomorrow:  (top 3)
```

## References

- Beginner how-to for every step: `SutraAI_Jetson_Beginner_Guide.md`
- Product map: `SutraAI_Solutions_Catalog.md` · UI target for Month 2: the `SutraAI UI Flow` canvas
- Reference projects: [#16060](https://studio.edgeimpulse.com/public/16060/latest) · [#510570](https://studio.edgeimpulse.com/public/510570/live) · [#348027](https://studio.edgeimpulse.com/public/348027/latest) · [#208622](https://studio.edgeimpulse.com/public/208622/latest)
- Jetson AI Lab: [Nemotron3 Nano 4B](https://www.jetson-ai-lab.com/models/nemotron3-nano-4b) · [Cosmos Reason 2 2B](https://www.jetson-ai-lab.com/models/cosmos-reason2-2b) · [NanoOWL](https://www.jetson-ai-lab.com/tutorials/nanoowl)
