Skip to content

fix(nn): correct center-coordinate IoU in Sophon YOLO NMS - #159

Open
nquyencubas523-cloud wants to merge 1 commit into
mainfrom
codex/fix-sophon-nms-center-coordinates
Open

fix(nn): correct center-coordinate IoU in Sophon YOLO NMS#159
nquyencubas523-cloud wants to merge 1 commit into
mainfrom
codex/fix-sophon-nms-center-coordinates

Conversation

@nquyencubas523-cloud

@nquyencubas523-cloud nquyencubas523-cloud commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix Sophon YOLO NPU postprocessing so NMS compares overlap using each box's center coordinates. Unequal full-body and partial-body detections can now suppress correctly at the configured threshold, while adjacent unequal boxes avoid an inflated overlap calculation.

Related issue

Closes #158.

Root cause

The NPU decoder emits center-format x, y, width, height. NMS previously interpreted x, y as upper-left corners. The output parser subsequently converts centers to upper-left coordinates, so saved event coordinates were correct even though the earlier NMS calculation was wrong.

The fix converts each center to its own edges only during IoU calculation. The surviving coordinates, score ordering, strict IoU > threshold comparison, and output contract remain unchanged.

Scope

In scope

  • Extract the existing NMS implementation into a dependency-free helper used by the production Sophon node.
  • Correct overlap geometry and add five focused regression cases.

Out of scope

  • Threshold defaults, confidence filtering, model weights, tracking, and class policy.
  • Authorization status UI/CLI compatibility and external configuration synchronization.

Risk tags

  • Model / inference / flow

Type of change

  • Bug fix
  • Test

Area

  • Model import / model runtime

Candidate identity

  • Base commit: 0dab89eea2e84835e0852dc10d2115e201237a03
  • Candidate commit: f535c487ca951e68ca9ab7f32ad754bfb5bdb236
  • Candidate tree: 06eba0b56f1486b2e88547d47eae864188166659
  • Package SHA-256: 9e82f7bd05734e4d8fe6bc2e1f1b9ff97e51baee26f010c83b625c5eb3c7eef4
  • AArch64 test binary SHA-256: d3ea266033589286be14c46a7a7bd7ca0bc87f7c5a5d2cf95fd7e09cc1aa33d2

No source changes, amendments, or rebases occurred after validation.

Verification

Parent baseline

Existing BM1688 installation: normal authenticated picture-task inference reproduced one same-person double detection in a set of 59 identical input images, with NMS 0.35 and task confidence 0.8. This is a measured deployed-version baseline, not a full build/test of the parent commit. A separate full parent suite was not run.

Candidate checks

Linux x86_64 build host:
  bash scripts/build_cpu_test.sh
  ./build_cpu/cosmo-tests --reporter junit --out <private-run>/cpu-tests-retry1.xml
  PASS: full suite, exit 0; JUnit failures=0, errors=0, skipped=0.

Formatting:
  bash scripts/format_check.sh --staged --check
  PASS before commit; final clang-format 18 dry-run over all four changed files also passed.

BM1688 Protected package:
  COSMO_MODEL_GUARD_BUILD_PROFILE=production-release
  COSMO_MODEL_GUARD_SDK_ROOT=<admitted-production-sdk>
  COSMO_PACKAGE_MODELS=preserve bash scripts/build.sh -T -c bm1688
  PASS: build, SDK admission, package regression checks, installed ELF audit,
  and final package verification; development mode disabled.

Actual BM1688 device, package libraries:
  LD_LIBRARY_PATH=<candidate-package>/lib <candidate-tests> '[nn][sophon][nms]'
  PASS: 5 test cases, 36 assertions.

Initial build attempts failed on host tool availability/compatibility. Task-local tools resolved those failures; failed and successful attempts are retained in private evidence. No tracked third-party files or global host configuration were changed.

Risk-based evidence

  • API/network: normal authenticated picture APIs; temporary runtime had isolated user, mount, PID and network namespaces with loopback-only routes.
  • Media/streaming: 59 still-image comparisons from the same input bytes, followed by a 110-second recording of the actual installed channel preview (more than three source loops). The operator independently confirmed that NMS 0.35 suppresses the duplicate and 0.4 retains both, consistent with the corrected overlap boundary. Preview output can reuse recent detection results and is not an exact raw per-frame NMS trace; no broad tracking or recall claim is made.
  • Sophon/device: real BM1688 and the same protected model/configuration. At NMS 0.35 and confidence 0.8, the reproduced duplicate changed from two boxes to the higher-confidence full-body box. The other 58 target lists were exactly unchanged, including two visually checked adjacent-person pairs. No additional target was removed in this sample set.
  • Frontend/UI: no UI change. A pre-existing authorization status query passes an unsupported --store-dir argument to the production provisioner and reports unknown; direct provisioner status returned valid, and protected CEM v2 loading and real inference succeeded.
  • Package/deployment: after the temporary device validation, the same production Protected package was installed through the normal authenticated upload and System/Upgrade path. The device rebooted successfully and reports V1.1.115.0. The running process executable SHA-256 is acda69e87a64d481427d9c2b185a8bbf116b2dcdaf12409a2208728655881860, matching the verified package. Existing protected model bytes and authorization certificates were preserved; direct provisioner status is valid and model initialization/inference succeeded. The temporary engine, picture task and algorithm were cleaned up.

Documentation impact

  • Documentation is not needed for this change.

Compatibility and deployment impact

  • This change is backward compatible.

Configuration and model formats are unchanged. Corrected overlap can change detection selection when box sizes differ. These samples do not establish universal recall in crowded or heavily occluded scenes.

Third-party code and assets

  • This PR does not add third-party code, models, datasets, media, or generated assets.
  • This PR does not include GPL, AGPL, or other strong copyleft code.

Security and release checklist

  • No secrets, tokens, private keys, or certificates are included.
  • No real device SN values, customer names, or private IPs are included.
  • No private model weights or proprietary download links are included.
  • New dependencies have an acceptable license and are documented. (No new dependencies.)
  • Documentation was updated if behavior changed. (Internal geometry correction; no configuration/API change.)
  • My commits are signed off with Signed-off-by: according to the DCO-style requirement in CONTRIBUTING.md.
  • I have read CONTRIBUTING.md and CODE_OF_CONDUCT.md.

Acceptance and cleanup

  • Candidate-bound acceptance: measured PASS for candidate and package hashes above, including official installation and running-binary identity. The final observed model NMS is 0.35 and task confidence is 0.8. A separate configuration save replaced a temporary 0.29 setting; the latest base code reloads affected tasks on SaveConfig. This is not attributed to an internal default-reset timer. GitHub checks passed (frontend build was correctly skipped for this C++ change).
  • Device test filter: [nn][sophon][nms].
  • Device backup state: a complete pre-upgrade application/configuration/certificate archive and a consistent SQLite backup were verified and retained privately for recovery. Post-upgrade model and certificate identities were checked. Concurrent operator configuration changes were preserved rather than overwritten.
  • Temporary-data cleanup: temporary task/algorithm deleted and temporary runtime stopped; private validation artifacts retained outside tracked paths.
  • Final Git status: clean.
  • Evidence was collected from the candidate commit listed above.
  • Any source change after validation invalidated and restarted the required checks. (No subsequent source change.)
  • No temporary credentials, media, models, device exports, or generated packages are included.

Notes for reviewers

Regression cases cover unequal duplicate boxes, reversed confidence order, translated coordinates, adjacent unequal boxes, strict threshold boundaries, touching/separate boxes, and empty/single input. Saved integer boxes alone cannot prove the exact floating-point IoU used before NMS; acceptance above uses actual before/after inference.

Preserve center-format output while correcting per-box corner calculation. Add CPU regressions for duplicate and neighboring boxes, score order, output coordinates and threshold boundaries.

Fixes #158

Signed-off-by: Nquyen Cubas <nquyencubas523@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(nn): Sophon YOLO NMS treats center coordinates as top-left corners

1 participant