Views
No views yet
.aimodel)
import CoreAIOps; no session, no model plumbing, downloads on first use):let boxes = try await CoreAI.detect(inImageAt: url)1git clone https://github.com/john-rocky/coreai-kit
2open coreai-kit/Examples/DetectCamera/DetectCamera.xcodeproj
3# → Run, then pick "Nano" in the model picker
4
5# agents / headless (macOS):
6cd coreai-kit/Examples/DetectCamera
7swift run detect-cli --model rf-detr --image Resources/gate_image.jpg1import CoreAIKitVision
2
3let detector = try await KitDetector(catalog: "rf-detr")
4let image = try ImageFile.load(imageURL) // any image file → CGImage + EXIF orientation
5let detections = try await detector.detect(in: image.cgImage)
6// detections: [Detection] — label, score, normalized box (top-left origin)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.
Real time? Use detect(in: CVPixelBuffer) — vImage scales the frame with no CGImage
round-trip; CameraFeed (kit API) streams the buffers.https://github.com/john-rocky/coreai-kit → product CoreAIKitVisionNSCameraUsageDescription — only for the live camera; the snippet needs nonedownloadProgress callback)| file | input | params | M4 Max GPU | iPhone 17 Pro GPU |
|---|---|---|---|---|
rfdetr-nano_float32.aimodel | 384×384 | 30.5M | 8.6 ms (~116 FPS) | ~25 ms (33–39 FPS live) |
rfdetr-small_float32.aimodel | 512×512 | 32.1M | 12.0 ms (~83 FPS) | — |
rfdetr-medium_float32.aimodel | 576×576 | 33.7M | 14.8 ms (~68 FPS) | 56–63 ms (15–17 FPS live) |
rfdetr-large_float32.aimodel | 704×704 | 33.9M | 19.1 ms (~52 FPS) | — |
input "image" [1, 3, R, R] float32, RGB in [0, 1] (ImageNet mean/std folded in-graph)
output "dets" [1, 300, 4] boxes, cxcywh normalized to [0, 1]
output "labels" [1, 300, 91] raw class logits; column index = ORIGINAL COCO id (0 unused, 1=person … 17=cat … 90)1import numpy as np, coreai.runtime as rt
2
3model = await rt.AIModel.load(path, rt.SpecializationOptions.default())
4fn = model.load_function("main")
5out = await fn({"image": rt.NDArray(rgb01)}) # rgb01: [1,3,R,R] in [0,1]
6prob = 1 / (1 + np.exp(-out["labels"].numpy()[0])) # [300, 91]
7scores, classes = prob.max(-1), prob.argmax(-1) # column index IS the COCO id
8boxes = out["dets"].numpy()[0] # cxcywh, multiply by image W/H
9keep = scores > 0.5 # done — no NMSrfdetr-seg-{nano,small,medium,large,xlarge,2xlarge}_float32.aimodel — same
contract plus masks [1, Q, R/4, R/4]: per-query FULL-FRAME logit planes at
stride 4 (host: sigmoid > 0.5; no ROI plumbing, no NMS). All six gate on CPU
and GPU with binary-mask IoU 1.000 on stable scenes. M4 Max GPU:
seg-nano 312² 10.7 ms → seg-2xlarge 768² 59.1 ms.
split/)split/rfdetr-{nano,medium}_{backbone,head}.aimodel separate the pure-ViT
backbone (image → features) from the deformable head (features → dets/labels;
position encodings baked in). The chain is bit-exact vs the monolith. Purpose:
per-stage compute-unit preferences — e.g. backbone on the Neural Engine.
Measured honestly: on iOS 27 beta the runtime still executes the backbone on
the GPU delegate even under .neuralEngine preference (identical detection
fingerprint, no ANE-compile pause), so today the monolith on GPU is the
fastest config; the split exists so ANE placement can be adopted the moment
the runtime honors it. Regenerate with export_rf_detr.py --variant <v> --split.conversion/export_rf_detr.py
from rfdetr==1.7.1 weights. The port surfaced four Core AI converter/runtime bugs
(float-arg arange abort, int64-comparison buffer clobber, GPU-delegate
floor/trunc/ceil = identity, cast-pair cancellation) — each worked around numerically
identically; details and minimal repros in
zoo/rf-detr.md.