feat: Update CoreML device support and server controls

- Replace 'mps' with 'coreml' as the identifier for Apple CoreML Execution Provider across the codebase.
- Remove Apple chip generation checks and ensure CoreML is available on all macOS arm64 devices.
- Adjust ONNX Runtime session creation to use default CoreML configurations without forcing 'MLProgram'.
- Implement support for MoGe-2 to utilize CoreML with static input shape requirements.
- Enhance server panel to display restart and stop controls consistently across running states, including 'BUSY'.
- Update UI tests to verify new behavior for server controls and cached model display.
- Bump blendjob dependency version to 0.1.16 in packaging tests and configurations.
This commit is contained in:
2026-09-02 10:50:02 +08:00
parent 7f6e47432e
commit 5a011b3b57
24 changed files with 619 additions and 117 deletions

View File

@@ -1,7 +1,4 @@
import functools
import platform
import re
import subprocess
import sys
import bpy
@@ -26,55 +23,34 @@ REQUIRED_MODEL_KEYS = (
DEVICE_LABELS = {
"cuda": ("CUDA", "NVIDIA CUDA"),
"directml": ("DirectML", "Windows GPU (DirectML)"),
"mps": ("MPS", "Apple Metal (MPS)"),
"coreml": ("CoreML", "Apple CoreML"),
"cpu": ("CPU", "CPU"),
}
APPLE_SILICON_PATTERN = re.compile(r"\bApple M(\d+)\b", re.IGNORECASE)
def parse_apple_silicon_generation(brand):
match = APPLE_SILICON_PATTERN.search(str(brand))
return int(match.group(1)) if match else None
@functools.lru_cache(maxsize=1)
def apple_silicon_generation():
if sys.platform != "darwin" or platform.machine().lower() not in {
def supports_coreml():
return sys.platform == "darwin" and platform.machine().lower() in {
"arm64",
"aarch64",
}:
return None
try:
result = subprocess.run(
("sysctl", "-n", "machdep.cpu.brand_string"),
check=True,
capture_output=True,
text=True,
timeout=2,
)
except (OSError, subprocess.SubprocessError):
return None
return parse_apple_silicon_generation(result.stdout)
def supports_mps(generation=None):
if generation is None:
generation = apple_silicon_generation()
return generation is not None and generation >= 4
}
def supported_devices():
devices = runtime.environment_manifest().get("devices")
if isinstance(devices, list) and devices:
names = [str(device).lower() for device in devices]
if not supports_mps():
names = [name for name in names if name != "mps"]
names = [
name
for device in devices
if (name := str(device).lower()) in DEVICE_LABELS
]
if not supports_coreml():
names = [name for name in names if name != "coreml"]
elif "cpu" in names:
names = ["cpu", *(name for name in names if name != "cpu")]
return names or ["cpu"]
if sys.platform == "win32":
return ["directml", "cpu"]
return ["mps", "cpu"] if supports_mps() else ["cpu"]
return ["cpu", "coreml"] if supports_coreml() else ["cpu"]
def device_enum_items(_owner, _context):