What is Reflex?

Reflex is the reflex arc for embedded robots on Arm: a closed camera -> perception -> decision -> actuation loop with a hard end-to-end latency budget, taken from a naive fp32 pipeline to an Arm-tuned int8 one by a six-rung optimization ladder that pays the full quality bill at every step — and picks every configuration by p99, because a reflex loop is judged by its worst frame, not its median.

Track framing (Physical AI)

  • Perception-to-action on sensor data. The loop is the physical-AI primitive: sensor frame in, brake/clear actuation signal out, with the decision stage (constant-velocity tracker + ego-corridor intersection) scored against ground-truth collision-course labels.
  • Simulated sensor feed, explicitly allowed by the track. Frames come from a deterministic procedural simulator (640x480 overhead camera, moving obstacles, seeded). We chose simulation because it emits perfect ground truth: every latency claim ships with an exact AP@0.5 and brake-decision delta instead of "it looks fine".
  • Honest scope statement (put this verbatim on Devpost): Reflex runs on simulated sensor data only. No robot hardware was used and no robot-hardware performance is claimed. Benchmarks ran on Apple M1 Max (macOS arm64) and Neoverse N2 (GitHub ubuntu-24.04-arm CI) as stand-ins for the Arm embedded/edge CPU class; rung ordering is expected to transfer to robot-class Arm SoCs, absolute numbers are not.

What it does

  1. sim/ generates a seeded episode with exact ground-truth boxes, velocities, and collision-course labels — zero external data.
  2. perception/ runs YOLOX-Nano (ONNX Runtime, CPU EP) through preprocess -> inference -> decode/NMS, each stage timed per frame.
  3. A tracker + corridor check turns detections into a per-frame BRAKE/CLEAR signal.
  4. reflex/ladder.py climbs six rungs (R0 naive fp32 baseline; R1 vectorized uint8 preprocessing; R2 static int8 QDQ quantization; R3 threads x provider sweep; R4 resolution policy incl. a closed-loop adaptive controller; R5 combined shipping config), emitting one session JSON with every raw sample, host + Arm ISA probe, and a verbatim repro command per rung.
  5. report/generate.py renders a single-file, no-dependency HTML report: p99 budget bullets, stage waterfall, latency-quality frontier, thread-scaling knee with p50 and p99, per-frame timeline.

Results (blessed 500-frame session, Apple M1 Max)

  • Sensor-to-signal p99: 25.78 -> 11.20 ms (2.30x); p50 24.13 -> 8.76 ms (2.76x); loop rate 41 -> 108 fps — from 30 fps-marginal to comfortably inside a 33 ms reflex budget with headroom.
  • The quality bill, paid in public: AP@0.5 vs exact simulator ground truth went up 0.346 -> 0.393 under int8 (out-of-domain workload); brake-decision accuracy 0.686 -> 0.666 (10 of 500 must-brake frames traded); model 3.66 -> 1.23 MB.
  • The p99 story (the differentiator): 8 threads ties 4 threads on median (8.79 vs 8.75 ms) but fattens the tail (p99 16.09 vs 11.03 ms). Median-based selection ships the jitterier config; Reflex selects on p99 and ships 4 threads. The worst frame is the one that meets the wall.
  • Cross-silicon (Neoverse N2, CI quick mode): overall p50 45.1 -> 16.0 ms (2.8x); the int8 rung alone is 1.85x on N2 vs 1.68x on M1 Max — the quantization win grows on silicon with i8mm, and the session records the ISA probe that says so.

Why it fits "AI optimization on Arm"

Every rung is an Arm-specific optimization with its mechanism named and measured: cv2's NEON uint8 resize path (R1), int8 GEMMs hitting MLAS sdot/udot kernels (R2), the thread-scaling knee of a small model on big.LITTLE-class cores (R3), and a latency-quality exchange rate spent by a controller under a budget (R4). Nothing is asserted from a datasheet; the harness measures it and stores the samples.

What is reusable beyond the demo

  • The simulator: seeded procedural episodes with perfect ground truth — a drop-in way to give any perception benchmark an exact quality bill.
  • The ladder harness: rung schema, per-stage timing, p99-first selection policy, session JSON with embedded repro commands, and a structural validator — model- and task-agnostic.
  • The report generator: session JSON -> single-file HTML with zero JS dependencies.

Try it

See README "Quick start": venv + pip, python -m perception.fetch_model (SHA-256-verified official YOLOX-Nano) + python -m perception.quantize, then python -m reflex.ladder --quick and python -m report.generate. Quick mode runs in a few minutes on any Apple Silicon or aarch64 Linux box; CI proves the same commands on a fresh Neoverse N2 runner.

Built With

Share this project:

Updates