Skip to content

Add optimized YOLOv10n ONNX reference port (721s to ~8s on ET-SoC1) - #224

Open
ruimouradev wants to merge 11 commits into
aifoundry-org:mainfrom
ruimouradev:port/yolov10n-onnx-reference
Open

Add optimized YOLOv10n ONNX reference port (721s to ~8s on ET-SoC1)#224
ruimouradev wants to merge 11 commits into
aifoundry-org:mainfrom
ruimouradev:port/yolov10n-onnx-reference

Conversation

@ruimouradev

Copy link
Copy Markdown

Summary

Adds a pinned-ONNX YOLOv10n reference port for ET-SoC1 and optimizes it from the
initial working port at 721.396s down to ~7.96s on the board, about 90x,
keeping full FP32 numerical correctness. Model identity is pinned in
artifacts.json (onnx-community/yolov10n, fixed revision and sha256).

Approach

All of the optimization is in src/ref_runtime.c. The graph is memory bound on
ET-SoC1, so the wins come from spreading work across all 16 harts and from the
vector unit, never from lowering precision.

  • Conv across harts. Each convolution splits by output channel, every hart
    writing a disjoint cache-line-aligned slice. L1 is minion-local and not
    coherent, so two harts never share a line.
  • 1x1 conv on the vector unit. The dominant 1x1 stride-1 path runs eight
    spatial positions at a time with packed FMA, two output channels sharing each
    activation load.
  • SiLU fused and vectorized. Sigmoid and Mul fold into one pass using the
    hardware packed exponential and reciprocal, so the intermediate is never
    materialized.
  • Serial ops parallelized. Elementwise, Concat, Softmax, MatMul, MaxPool,
    Transpose, Split, Reshape and ReduceMax each ran on a single hart. All of them
    now split across 16 with the same cache-line-aligned publish discipline.
  • Depthwise 3x3 on the vector unit, plus an O(1) TopK early reject.

Each step was validated on the board before being kept. Loop-order cache-blocking
of the convs and running them on the tensor engine both regressed on this
memory-bound graph and were dropped.

Results

Board runs on ET-SoC1 (aifoundry2), metric Kernel wait seconds.

build time
baseline, initial working port 721.396s
this PR, three runs 7.95956s / 7.95906s / 7.95894s
this PR through run_sysemu_model_ports.sh 7.99992s, pass

tools/compare_full.py reports FULL_COMPARE PASS on every run above, 16
checkpoints at atol=5e-5 rtol=1e-4, against a host oracle built from the pinned
ONNX model. FP32 throughout, and the host build is clean under
-Wall -Wextra -Werror.

Benchmark registration

Registered as models.yolov10n_hf_reference so board CI selects and scores it,
with the deterministic input and weight blobs under assets/ as file_loads.
src/leaderboard_full.c is the single translation unit the leaderboard build
wants, compiling the same units and flags the scripts use separately. I built that
ELF on the board with its own toolchain and ran it there as a check: pass,
8.22834s, FULL_COMPARE PASS, same output bytes.

The entry declares src/ as the port's source root so host_full_runner.c and
host_range_runner.c do not trip the coverage check. They are the x86 host oracle
this port validates against, so they cannot be in a board ELF, and the config has
no way to mark a source as host-side. Glad to move them out of src/ instead if
you prefer.

Notes

Outside the port directory this touches only the benchmark_config.json entry, a
.gitignore exception for the committed benchmark blobs (same pattern as yolo
and dncnn), and the model line in the top-level README list. data/*.json and
the generated leaderboard block are left for CI. No submodule changes.

@ruimouradev
ruimouradev requested a review from AFOliveira as a code owner July 26, 2026 10:14
@github-actions github-actions Bot added track: model-ports Global approved model ports prize track: community Community support and ecosystem contributions labels Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

track: community Community support and ecosystem contributions track: model-ports Global approved model ports prize

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants