Skip to content

Commit 3018b67

Browse files
committed
Occlusion Stress-Test generation. Automated failure gallery
1 parent fc769c3 commit 3018b67

5 files changed

Lines changed: 1322 additions & 18 deletions

File tree

README.md

Lines changed: 118 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Zero-Shot SKU Onboarding — Zippin Edge AI Platform (v2.0)
22

3-
![Python](https://img.shields.io/badge/python-3.10%2B-blue) ![License](https://img.shields.io/badge/license-MIT-green) ![CI](https://github.com/pranavkoduru/zippin-synthetic-onboarding-poc/actions/workflows/ci.yml/badge.svg)
3+
![Python](https://img.shields.io/badge/python-3.10%2B-blue) ![License](https://img.shields.io/badge/license-MIT-green) ![CI](https://github.com/Pranavk098/zippin-synthetic-onboarding/actions/workflows/ci.yml/badge.svg) ![Edge Optimized](https://img.shields.io/badge/edge--optimized-Jetson%20Orin%20NX-76b900?logo=nvidia) ![TensorRT Ready](https://img.shields.io/badge/TensorRT-FP16%20%7C%20INT8-76b900?logo=nvidia) ![Blender Scripted](https://img.shields.io/badge/BlenderProc2-domain%20randomisation-orange?logo=blender)
44

55
A production-grade, end-to-end pipeline that onboards a **new retail SKU in under 10 minutes** from a single product photograph — no real-world data collection required.
66

@@ -124,16 +124,21 @@ zippin-synthetic-onboarding-poc/
124124
│ │ ├── extract.py ← Stage 1: LLaVA semantic extraction
125125
│ │ ├── generate.py ← Stage 2: BlenderProc2 orchestration
126126
│ │ ├── train.py ← Stage 3: YOLOv8n + EWC fine-tuning
127-
│ │ └── eval.py ← Stage 4: pycocotools mAP evaluation
127+
│ │ └── eval.py ← Stage 4: mAP eval + failure gallery
128128
│ ├── rendering/
129-
│ │ └── bproc_generator.py ← BlenderProc2 scene script
129+
│ │ └── bproc_generator.py ← BlenderProc2 + occlusion stress suites
130130
│ ├── api/
131131
│ │ ├── server.py ← FastAPI REST service
132132
│ │ └── schemas.py ← Pydantic request/response models
133133
│ └── utils/
134134
│ ├── coco_to_yolo.py ← COCO → YOLO format conversion
135135
│ ├── metrics.py ← pycocotools + NumPy mAP fallback
136136
│ └── sku_registry.py ← Thread-safe multi-SKU state store
137+
├── scripts/
138+
│ ├── benchmark_ewc.py ← EWC retention benchmark across N SKUs
139+
│ ├── export_tensorrt.py ← YOLOv8n → TensorRT FP16/INT8 engine
140+
│ ├── compute_dis.py ← Domain Invariance Score (CLIP embeddings)
141+
│ └── profile_edge.py ← Jetson Orin NX quantization profiler
137142
├── docker/
138143
│ ├── Dockerfile ← GPU worker (CUDA 12.1)
139144
│ ├── Dockerfile.jetson ← Jetson Orin NX (L4T aarch64)
@@ -254,6 +259,116 @@ approximately **25MB** for YOLOv8n. This is the entire continual learning memory
254259

255260
---
256261

262+
## Production QA Tooling
263+
264+
Four additional scripts address the failure modes that matter most in a real Zippin deployment:
265+
266+
### Occlusion Stress-Test Suite
267+
268+
Zippin's Chief Scientist has noted that small products can be completely covered by a shopper's hand during a pick event. The renderer now generates targeted stress suites alongside standard data:
269+
270+
```bash
271+
# Partial occlusion (30–55% SKU coverage) — reaching-arm events
272+
BPROC_OCCLUSION_MODE=partial_stress \
273+
blenderproc run src/rendering/bproc_generator.py checkpoints/sku_features.json
274+
275+
# Full occlusion (75–95% coverage) — product nearly invisible
276+
BPROC_OCCLUSION_MODE=full_stress \
277+
blenderproc run src/rendering/bproc_generator.py checkpoints/sku_features.json
278+
279+
# All three suites in sequence
280+
BPROC_OCCLUSION_MODE=all \
281+
blenderproc run src/rendering/bproc_generator.py checkpoints/sku_features.json
282+
```
283+
284+
Outputs to `checkpoints/synthetic_dataset/occlusion_stress/partial/` and `.../full/` with independent COCO annotations. Use the `full/` suite to calibrate the sensor-fusion confidence threshold in `src/proposals/sensor_fusion.py`.
285+
286+
---
287+
288+
### Domain Invariance Score (DIS)
289+
290+
Measures how well synthetic renders approximate the visual feature space of the original product photo using **CLIP ViT-B/32** embeddings. Catches Sim2Real gaps before they become mAP surprises on real shelf cameras.
291+
292+
```bash
293+
python scripts/compute_dis.py \
294+
--original product.jpg \
295+
--synthetic checkpoints/synthetic_dataset/images/ \
296+
--output checkpoints/dis_report.json
297+
```
298+
299+
```
300+
══════════════════════════════════════════════════════
301+
Domain Invariance Score (DIS) — clip-vit-b32
302+
══════════════════════════════════════════════════════
303+
DIS (mean cosine sim) : 0.8341 [PASS]
304+
Std deviation : 0.0412
305+
Range : [0.7190, 0.9203]
306+
p10 / p25 / p75 / p90 : 0.778 / 0.809 / 0.862 / 0.889
307+
n_renders : 50
308+
n < 0.70 (FAIL band) : 0
309+
n < 0.80 (WARN band) : 9
310+
══════════════════════════════════════════════════════
311+
```
312+
313+
| DIS Score | Status | Action |
314+
|---|---|---|
315+
| ≥ 0.80 | **PASS** | Tight alignment — proceed to training |
316+
| 0.70–0.80 | **WARN** | Increase render count or DR passes |
317+
| < 0.70 | **FAIL** | Check VLM attribute extraction (Stage 1) |
318+
319+
---
320+
321+
### Edge Quantization Profiler
322+
323+
Profiles FP32, FP16, and INT8 quantization tiers against the Jetson Orin NX SLA. Works in **simulation mode** on any laptop (no Jetson required) by projecting CPU timings to expected Jetson performance.
324+
325+
```bash
326+
# Full TensorRT profiling (requires CUDA)
327+
python scripts/profile_edge.py --weights checkpoints/new_sku_weights.pt
328+
329+
# Simulation mode (CPU → Jetson projection, works on any machine)
330+
python scripts/profile_edge.py --weights checkpoints/new_sku_weights.pt --simulate
331+
```
332+
333+
```
334+
══════════════════════════════════════════════════════════════════════
335+
Tier Backend p50 (ms) FPS Size MB SLA
336+
-------- -------------------- ------------ -------- ---------- ----
337+
FP32 PyTorch 31.4 31.8 12.1 FAIL
338+
FP16 PyTorch 11.8 84.7 6.1 PASS
339+
INT8 TensorRT 8.2 121.9 3.4 PASS
340+
══════════════════════════════════════════════════════════════════════
341+
Recommended: FP16 — best FPS/accuracy tradeoff for 60-FPS SLA
342+
INT8 recommended when thermal budget is constrained (outdoor venues)
343+
```
344+
345+
---
346+
347+
### Automated Failure Gallery
348+
349+
Every eval run automatically saves the **10 lowest-confidence images** to `checkpoints/failure_gallery/<job_id>/` with a ranked JSON summary. Zero-detection images (hardest cases) rank first.
350+
351+
```
352+
checkpoints/failure_gallery/abc123/
353+
├── 01_conf0.000_shelf_front_01.jpg ← no detection (full occlusion?)
354+
├── 02_conf0.182_shelf_angle_07.jpg ← low confidence (lighting?)
355+
├── 03_conf0.241_shelf_tilt_03.jpg
356+
├── ...
357+
└── gallery_summary.json
358+
```
359+
360+
```json
361+
{
362+
"rank": 1,
363+
"max_confidence": 0.0,
364+
"n_detections": 0,
365+
"diagnosis_hint": "No detections — possible full occlusion, extreme angle,
366+
or severe domain shift."
367+
}
368+
```
369+
370+
---
371+
257372
## Background: Why This Architecture?
258373

259374
At ATAI Labs, Pranav reduced end-to-end multi-stream inference latency from 8.0s to 1.5s via TensorRT dynamic batch scheduling and layer fusion on NVIDIA A100 clusters. The design choices here apply the same discipline — optimising every component against the hardware ceiling (Jetson Orin's 8GB VRAM and 60 FPS SLA) rather than building for demo conditions.

0 commit comments

Comments
 (0)