Skip to content

Add Core ML export support - #172

Merged
brohoya merged 14 commits into
LibreYOLO:mainfrom
aalvsz:90-add-coreml-support
May 15, 2026
Merged

brohoya merged 14 commits into
LibreYOLO:mainfrom
aalvsz:90-add-coreml-support

Conversation

@aalvsz

@aalvsz aalvsz commented May 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add Core ML export support and register it in the exporter registry
  • add CoreMLBackend dispatch for .mlpackage outputs
  • document the RF-DETR conversion blocker and validation notes
  • include iPhone validation report for the Core ML path

Authorship

  • rebuilt the branch with commits authored and committed by aalvsz only

Tests

  • not run in this PR creation step; branch already contains the committed validation report

Related to #90.

@aalvsz
aalvsz force-pushed the 90-add-coreml-support branch from 38ad463 to 582ea36 Compare May 3, 2026 21:06
@EHxuban11
EHxuban11 requested a review from brohoya May 3, 2026 21:13
@brohoya

brohoya commented May 4, 2026

Copy link
Copy Markdown
Contributor

Hi @aalvsz, thanks for the contribution!

Before we can review/merge this, could you please clean up the PR by removing any unrelated docs/validation artifacts?

Also, could you add a short explanation of how you tested the changes, including the commands or steps we can run locally to verify that everything works?

Thanks!

@aalvsz

aalvsz commented May 6, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I’ve now addressed both items.

I removed the unrelated/unneeded materials.

Committed as: ed94569

Validation run locally:

  • pytest tests/unit/test_export_coreml.py -q
  • pytest tests/e2e/test_coreml_roundtrip.py -q -m coreml (will skip RF-DETR NMS test)

Add CoreML (.mlpackage) as a new export format and a CoreMLBackend
that runs the exported model on macOS via coremltools.

* Register CoreMLExporter in the BaseExporter registry.
* Implement export_coreml() with per-family preprocess wrappers so
  the traced graph always accepts canonical RGB float in [0, 1].
* Embed Apple's NonMaximumSuppression as a CoreML pipeline when
  nms=True (raises for RF-DETR; not supported).
* Add CoreMLBackend mirroring OnnxBackend; dispatch .mlpackage
  directories from the LibreYOLO() factory.
* Add coremltools optional extra and the 'coreml' pytest marker.
* Add unit tests (mock coremltools so they run on Linux) and a
  macOS-only e2e parity suite.

Rebased onto current main, squashing 11 prior commits while
preserving the original authorship.
@brohoya
brohoya force-pushed the 90-add-coreml-support branch from 92fd238 to 150358e Compare May 11, 2026 18:51
Comment on lines +684 to +689
class CoreMLExporter(BaseExporter):
format_name = "coreml"
suffix = ".mlpackage"
requires_onnx = False
supports_int8 = False
apply_model_half = False # ct.convert handles precision via compute_precision

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @aalvsz, I noticed that CoreMLExporter is missing the supports_fp16 class attribute that every other BaseExporter subclass declares. This makes libreyolo formats crash:

libreyolo formats
╭───────────────────────────────────────────── Traceback (most recent call last) ─────────────────────────────────────────────╮
│ /home/bix/Documents/libreyolo/libreyolo/cli/commands/special.py:216 in formats_cmd                                          │
│                                                                                                                             │
│   213 │   │   │   "name": name,                                                                                             │
│   214 │   │   │   "extension": cls.suffix,                                                                                  │
│   215 │   │   │   "int8": cls.supports_int8,                                                                                │
│ ❱ 216 │   │   │   "fp16": cls.supports_fp16,                                                                                │
│   217 │   │   │   "requires_onnx": cls.requires_onnx,                                                                       │
│   218 │   │   }                                                                                                             │
│   219 │   │   if name == "tensorrt":                                                                                        │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: type object 'CoreMLExporter' has no attribute 'supports_fp16'

Fix:

Suggested change
class CoreMLExporter(BaseExporter):
format_name = "coreml"
suffix = ".mlpackage"
requires_onnx = False
supports_int8 = False
apply_model_half = False # ct.convert handles precision via compute_precision
class CoreMLExporter(BaseExporter):
format_name = "coreml"
suffix = ".mlpackage"
requires_onnx = False
supports_int8 = False
supports_fp16 = True
apply_model_half = False # ct.convert handles precision via compute_precision

@brohoya
brohoya force-pushed the 90-add-coreml-support branch from c0fef03 to 6fc0dad Compare May 15, 2026 17:07
@brohoya
brohoya merged commit f5a9089 into LibreYOLO:main May 15, 2026
@brohoya brohoya mentioned this pull request May 17, 2026
marikazimut pushed a commit to marikazimut/libreyolo that referenced this pull request Jun 21, 2026
marikazimut pushed a commit to marikazimut/libreyolo that referenced this pull request Jun 21, 2026
Brings to dev: CoreML export+backend (LibreYOLO#172), validation imgsz override
honored (LibreYOLO#232), YOLO9 imgsz fix (LibreYOLO#208), 80-class hardcode fix (LibreYOLO#209),
README flagship rhetoric (LibreYOLO#233), Chinese README, plus the smaller fixes
that landed on main since the last dev sync.

Conflict resolution:
- pyproject.toml: union extras (keep both `gaze`/`gaze-retinaface` from
  dev and `coreml` from main); add both `libreyolo[gaze]` and
  `libreyolo[coreml]` to `all`. Keep dev's `rfdetr = [transformers,
  scipy]` (native RF-DETR port; do not pull in main's third-party
  `rfdetr` package). Keep main's tensorrt pin + uv dependency-metadata
  blocks (auto-merged). Union pytest markers (auto-merged).
- validation/detection_validator.py: auto-merged. Main's `_resolve_imgsz`
  helper and explicit-imgsz fix combine cleanly with dev's TTA additions
  (`_run_validation_augmented`, `_uses_topk_coco_scoring`, etc.). Main's
  removal of the `_coco_annotation_file is not None` topk precondition
  is preserved implicitly via dev's family-only helper.
- data/utils.py: auto-merged. PRs LibreYOLO#186/LibreYOLO#192 landed on both sides, so the
  symlink-resolve and exists-check removals match; dev's Windows-sep
  handling and multi-split-list support preserved.
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.

2 participants