Skip to content

yolo-detection-2026: mps backend crash-loops with "No module named 'ultralytics'" (requirements_mps.txt intentionally excludes it) #208

Description

@solderzzc

Summary

On Apple Silicon (mps backend), the yolo-detection-2026 skill crash-loops on startup with:

Failed to load model: No module named 'ultralytics'

even though requirements_mps.txt deliberately does not install ultralytics/torch — by design, the mps install path is meant to run inference through onnxruntime + CoreMLExecutionProvider only, using the pre-built yolo26n.onnx shipped in the repo.

Reported by @brianmrobertson in #207 on an Apple M1 Pro (16GB unified memory):

[env_config] Apple Silicon: Apple M1 Pro (16384MB unified)
[env_config] Optimized runtime not installed for mps, will use PyTorch fallback
[env_config] Detected: backend=mps, device=mps, gpu=Apple M1 Pro, format=onnx, framework_ok=False
{"event": "progress", "stage": "model", "message": "Loading yolo26n model (onnx format)..."}
{"event": "error", "message": "Failed to load model: No module named 'ultralytics'", "retriable": false}

This repeats through [Aegis] Crashed (exit 1). Restarting (1/3)... up to (3/3), then the process exits permanently with code 1 — the skill is completely unusable on this hardware/install combination, with no automatic recovery.

Root cause

skills/detection/yolo-detection-2026/scripts/env_config.py:

  1. _check_mps_runtime() (line 525) gates framework_ok on onnxruntime exposing CoreMLExecutionProvider:

    import onnxruntime
    providers = onnxruntime.get_available_providers()
    if "CoreMLExecutionProvider" in providers:
        return True
    raise ImportError("CoreMLExecutionProvider not available")

    On this user's machine, the installed onnxruntime wheel apparently doesn't expose CoreMLExecutionProvider (generic PyPI onnxruntime on macOS arm64 doesn't always ship it), so this raises ImportError and framework_ok becomes False.

  2. load_optimized() (line 777) branches on framework_ok:

    if use_optimized and self.framework_ok:
        # ... MPS-specific path at line 792 calls self._load_onnx_coreml(),
        # which only needs onnxruntime, NOT ultralytics ...
    
    # No optimization requested or framework missing
    from ultralytics import YOLO   # <-- line 852, UNCONDITIONAL fallback
    model = YOLO(f"{model_name}.pt")

    When framework_ok is False, the code falls straight through to the bottom fallback branch, which unconditionally imports ultralytics regardless of backend. This is correct for cuda/intel/cpu backends (where requirements_*.txt does install ultralytics), but wrong for mps, whose requirements_mps.txt intentionally ships an ultralytics-free, onnxruntime-only install.

In short: the framework_ok gate conflates two different things — "CoreML EP is available" and "any usable runtime is available at all" — for the mps backend. When CoreML EP isn't available, the code should still be able to fall back to onnxruntime with CPUExecutionProvider (which _load_onnx_coreml's providers=['CoreMLExecutionProvider', 'CPUExecutionProvider'] list already supports as a second choice) instead of jumping to a ultralytics-only path that was never installed for this backend.

Suggested fix direction

In load_optimized(), the mps-backend branch (self._load_onnx_coreml(...)) should be reachable whenever the pre-built/cached .onnx model exists, independent of whether framework_ok (i.e. CoreML EP specifically) is True_load_onnx_coreml already provides a CPU-provider fallback via its own providers list. The ultralytics import at line 852 should only be reached for backends whose requirements_<backend>.txt actually installs ultralytics (i.e. never for mps).

Separately: deploy.sh's "Step 6: Verify installation" only calls HardwareEnv.detect() and prints the resulting dict — it never actually calls load_optimized() / attempts a real model load. So this exact failure mode is invisible at install time and only surfaces later, at runtime, as a crash-loop. Worth tracking as part of a broader look at whether skill deploy.sh "verification" steps do a real functional check vs. just probing hardware.

Environment

  • Apple M1 Pro, 16GB unified memory, macOS
  • DeepCamera skill: yolo-detection-2026 v2.0.0
  • Reported in Says SwiftLM Not Installed #207 (a different, already-resolved issue) — filing separately since this is a distinct root cause

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions