File size: 5,167 Bytes
b1e4751 fac480b 3fde452 3e1d8ff 3fde452 fac480b b1e4751 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | ---
license: apache-2.0
pipeline_tag: object-detection
library_name: coreai
tags:
- core-ai
- coreml
- object-detection
- yolox
- apple
base_model: Megvii-BaseDetection/YOLOX
---
# YOLOX-S — Core AI
[YOLOX](https://github.com/Megvii-BaseDetection/YOLOX) (Megvii, Apache-2.0) converted to
Apple **Core AI** (`.aimodel`) — a single-stage **anchor-free** object detector running as
one static graph on every Apple compute unit (Mac GPU / iPhone GPU / Neural Engine). Part
of the [Core AI model zoo](https://github.com/john-rocky/coreai-model-zoo)
([model card](https://github.com/john-rocky/coreai-model-zoo/blob/main/zoo/yolox.md)).
The **dense-detector** counterpart to
[RF-DETR-CoreAI](https://huggingface.co/mlboydaisuke/RF-DETR-CoreAI): where the DETR family
needs no NMS, YOLOX is the classic `score = obj · cls` + **per-class NMS** pipeline.
<!-- gen-cards:use-it begin id=yolox-s (managed by scripts/gen-cards — edit cards.json / QuickStart.swift, not this block) -->
## Use it
⚡ **One line** — run the kit's task op on this model
(`import CoreAIOps`; no session, no model plumbing, downloads on first use):
```swift
let boxes = try await CoreAI.detect(inImageAt: url, options: .model("yolox-s"))
```
Twenty ops, one shape — [Cookbook](https://github.com/john-rocky/coreai-kit/blob/main/docs/COOKBOOK.md).
▶️ **Run it (source)** — the [DetectCamera runner](https://github.com/john-rocky/coreai-kit/tree/main/Examples/DetectCamera)
(real-time object detection on the zero-copy camera path):
```bash
git clone https://github.com/john-rocky/coreai-kit
open coreai-kit/Examples/DetectCamera/DetectCamera.xcodeproj
# → Run, then pick "YOLOX" in the model picker
# agents / headless (macOS):
cd coreai-kit/Examples/DetectCamera
swift run detect-cli --model yolox-s --image Resources/gate_image.jpg
```
💻 **Build with it** — complete; the glue is kit API, copy-paste runs:
```swift
import CoreAIKitVision
let detector = try await KitDetector(catalog: "yolox-s")
let image = try ImageFile.load(imageURL) // any image file → CGImage + EXIF orientation
let detections = try await detector.detect(in: image.cgImage)
// detections: [Detection] — label, score, normalized box (top-left origin)
```
The take-home is [`Examples/DetectCamera/Sources/QuickStart.swift`](https://github.com/john-rocky/coreai-kit/blob/main/Examples/DetectCamera/Sources/QuickStart.swift)
— this exact code as one typed function, no UI; the CLI is an argument shell over it, and
the GUI runs the same detector per camera frame on a zero-copy pixel-buffer fast path.
YOLOX is a dense detector — `KitDetector` runs the obj·cls threshold + per-class NMS
host-side; the DETR family needs none. Same `detect(in:)` either way.
**Integration checklist**
- SPM: `https://github.com/john-rocky/coreai-kit` → product **CoreAIKitVision**
- Info.plist: `NSCameraUsageDescription` — only for the live camera; the snippet needs none
- Entitlements: none needed
- First run downloads the model — 0.0 GB (Mac) / 0.0 GB (iPhone) — then it loads from the
local cache (Application Support; progress via the `downloadProgress` callback)
- Measure in Release — Debug is ~3× slower on per-token host work
<!-- gen-cards:use-it end -->
## Bundle
- `yolox-s_float32.aimodel` — YOLOX-S, 640² input, 8.97M params, **fp32** (the ship dtype;
detection has no bandwidth-bound decode loop, so fp16 is no faster on the GPU and only adds
near-tie noise). 36 MB. Same bundle on macOS and iOS.
## Graph contract
```
input "image" [1,3,640,640] f32 BGR, 0-255, letterboxed (pad 114, top-left) — YOLOX-native (no /255, no mean/std)
output "preds" [1,8400,85] f32 [cx,cy,w,h, obj, cls_0..cls_79]; box DECODED to 640-px, obj/cls SIGMOID-ed (in-graph)
```
Host post-process: `score = obj · max_class`, threshold, **per-class NMS** (IoU 0.45), then
un-letterbox the survivors. Anchors A = 80² + 40² + 20² = 8400 (strides 8/16/32).
## Parity & speed (measured)
- **vs torch fp32:** head cosine **1.000000**, end-to-end detections IoU **1.000** on CPU and GPU.
- **M4 Max GPU: 4.80 ms / 208 FPS** (median). M4 Max CPU 57 ms.
- **iPhone 17 Pro** (Release, GPU, live camera): **~22 ms / 35–40 FPS** end-to-end; first-load
on-device specialization ~2.6 s (no AOT). The on-device gate reproduces the Mac fp32 oracle
**6/6** (cat 0.96/0.96, remote 0.86/0.86, bed 0.71, couch 0.54).
## Use (CoreAIKit)
```swift
import CoreAIKitVision
let detector = try await YOLOXDetector(model: .yoloxS) // downloads this repo
let detections = try await detector.detect(in: pixelBuffer, scoreThreshold: 0.3)
```
Live-camera + video reference app: **DetectCamera** in
[coreai-kit](https://github.com/john-rocky/coreai-kit).
## Convert it yourself
[`conversion/export_yolox.py`](https://github.com/john-rocky/coreai-model-zoo/blob/main/conversion/export_yolox.py)
— `--variant s --yolox-repo <YOLOX checkout> --weights yolox_s.pth`, gated end-to-end with
`--verify-image <img> --unit {cpu,gpu}`. The script also maps `nano`/`tiny`/`m`/`l`/`x`.
## License
Apache-2.0 — upstream YOLOX code and COCO-pretrained weights are Apache-2.0.
|