Free course · by the SutraCore team

Free NVIDIA Jetson AI course: 30 days, 16 steps

Orin NX 16GBJetPack 6.2.1CUDA 12.6TensorRT 10.3Python 3.10PyTorch 2.8
Step 13 of 16Day 21 · Sun 15 NovWeek 3Phase A · notebooks

Adoption gate

The go/no-go check before any web code. All four model types must run end to end from config files, from a clean kernel, with numbers you can repeat.

Runs on
JupyterLab on the Jetson
Notebooks
90_runner.ipynb (final)
Creates
configs/detect.yaml, reports/gate.md, git tag phase-a-done
Time
Day 21

Where Where to implement

Runner

  • Extend sutra_core/run.py so type: image and type: object_detection call your Step 04 and Step 09 code

Report

  • reports/gate.md: one row per model, generated by the notebook

Do Do it

1Add the detection config

Fileconfigs/detect.yaml
name: detect_v1
dataset: data/raw/detect
input:      { type: image, width: 96, height: 96, color: grayscale }
processing: { type: image, normalize: true }
learning:   { type: object_detection, arch: centroid_mobilenetv2_050, epochs: 60, lr: 0.001, object_weight: 20 }
export:     [onnx, tflite_int8, tensorrt]

2Route image and detection through run()

Wrap your Step 04 training code in train_image(cfg, out) and the Step 09 code in train_detect(cfg, out), both in sutra_core/train.py. Each returns a metrics dict. Then dispatch on the input or learning type:

Filesutra_core/run.py (inside run(), first lines)
cfg = yaml.safe_load(open(config_path))
out = Path(out_dir) if out_dir else ROOT
if cfg["learning"]["type"] == "object_detection":
    from .train import train_detect
    return train_detect(cfg, out)
if cfg["input"]["type"] == "image":
    from .train import train_image
    return train_image(cfg, out)
# ... timeseries path from Step 08 continues here

3Run all four from a clean kernel

Notebook cellnotebooks/90_runner.ipynb
import sys, json, time
from pathlib import Path
ROOT = Path.home() / "sutraai"; sys.path.insert(0, str(ROOT))
from sutra_core.run import run

results, timing = {}, {}
for name in ["image", "sensor", "audio", "detect"]:
    t = time.perf_counter()
    results[name] = run(ROOT / "configs" / f"{name}.yaml")
    timing[name] = round((time.perf_counter() - t) / 60, 1)

score = lambda m: m.get("test_f1", m.get("test_acc"))
lines = ["| model | metric | test score | minutes |", "|---|---|---|---|"]
for k, m in results.items():
    lines.append(f"| {k} | {'F1' if 'test_f1' in m else 'accuracy'} | {score(m):.3f} | {timing[k]} |")
(ROOT / "reports/gate.md").write_text("\n".join(lines)); print("\n".join(lines))

4Repeat once to prove it's stable

Kernel → Restart and Run All a second time. Every score should land within about 1 point (0.01 F1) of the first run. If not, check your seeds and data splits.

5Decide

All boxes below ticked: tag the repo and start Step 14 tomorrow.

Jetson terminal
cd ~/sutraai && git add -A && git commit -m "Phase A complete" && git tag phase-a-done

Something failing: use Days 22–23 to fix it and slide Phase B by up to two days. Don't start FastAPI with a broken model: debugging ML through a web stack is much harder.

Test Test it

Notebook cellnotebooks/90_runner.ipynb (last cell)
assert results["image"]["test_acc"] >= 0.85
assert results["sensor"]["test_acc"] >= 0.85
assert results["audio"]["test_acc"] >= 0.80
assert results["detect"]["test_f1"] >= 0.75
print("✅ ADOPTION GATE PASSED: go to Phase B")

Done The gate

  • NB00 is green (GPU, cuDNN, TensorRT, ONNX Runtime CUDA)
  • Image, sensor, audio and detection each go train → evaluate → export → int8 check
  • Every int8 model: accuracy drop under 3 points (detection: F1 drop under 0.05)
  • All four run from configs/*.yaml via run(), from a clean kernel
  • Second run reproduces scores within about 1 point
  • MFCC golden vectors and profile.md saved
  • Device simulator: v1 → v2 update, sha256 refusal, telemetry all work
  • Nemotron advisor correct; RAG hit@4 ≥ 8/10
  • Reusable code lives in sutra_core/, not only in notebook cells
  • BUILDLOG has the numbers; repo tagged phase-a-done

If it breaks

SymptomFix
One model passes in its own notebook but fails in run()A setting differs between the notebook and the YAML (size, lr, epochs, normalization). Diff them.
Scores jump between runsSeed random, numpy and torch at the top of run(); keep splits by file and seeded.
Kernel dies mid-runFree GPU memory between models: del model; torch.cuda.empty_cache() at the end of each train function.

Learn more