mirror of
https://github.com/hanzoai/ANE.git
synced 2026-10-30 18:53:51 +00:00
- ane_universal.h: Auto-detecting runtime that selects InMem (M4+) or CoreML fallback (M1-M3) based on hardware capability probing - ane_probe_m1.m: Deep diagnostic found all 74 ANE classes present on M1 but _ANECompiler binary rejects all MIL programs (40+ format combos) - ane_m1_fix.m: Systematic MIL format fuzzer (program versions 1.0-1.3, opsets ios15-ios18, weight offsets, old/new syntax) — all fail on M1 - ane_coreml_bridge.m: CoreML ANE bridge showing 2.44x speedup at 256x256 - benchmark_apple_silicon.py: MLX vs MPS vs CoreML comparison on M1 Max - MLX: 6.72 TFLOPS peak (fp16), 62ms/step training - MPS: 4.12 TFLOPS peak, 84ms/step training - ANE via CoreML: ~1x (dispatch overhead negates hardware advantage) - demo_mlx_training.py: Working 4-layer transformer training, 4688 tok/s - Updated README with M1-M4 compatibility matrix and integration points - Added .gitignore for compiled binaries and .venv
60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate a minimal CoreML model and extract the MIL text that M1 ANE accepts."""
|
|
import os
|
|
import coremltools as ct
|
|
import numpy as np
|
|
from coremltools.converters.mil import Builder as mb
|
|
|
|
print(f"coremltools: {ct.__version__}")
|
|
|
|
configs = [
|
|
(64, 64, 16, "small"),
|
|
(256, 256, 64, "medium"),
|
|
]
|
|
|
|
for CH_IN, CH_OUT, SEQ, label in configs:
|
|
print(f"\n{'='*60}")
|
|
print(f"Config: {label} — conv {CH_IN}→{CH_OUT}, seq={SEQ}")
|
|
|
|
@mb.program(input_specs=[mb.TensorSpec(shape=(1, CH_IN, 1, SEQ))])
|
|
def prog(x):
|
|
W = mb.const(val=np.random.randn(CH_OUT, CH_IN, 1, 1).astype(np.float16), name="W")
|
|
x_fp16 = mb.cast(x=x, dtype="fp16", name="x_fp16")
|
|
y = mb.conv(x=x_fp16, weight=W, strides=[1, 1], pad_type="valid", name="out")
|
|
return y
|
|
|
|
model = ct.convert(
|
|
prog,
|
|
compute_units=ct.ComputeUnit.CPU_AND_NE,
|
|
minimum_deployment_target=ct.target.macOS15,
|
|
convert_to="mlprogram",
|
|
)
|
|
|
|
pkg_path = f"/tmp/ane_m1_{label}.mlpackage"
|
|
model.save(pkg_path)
|
|
print(f"Saved: {pkg_path}")
|
|
|
|
# Walk the package and dump text files
|
|
for root, dirs, files in os.walk(pkg_path):
|
|
for f in sorted(files):
|
|
fp = os.path.join(root, f)
|
|
sz = os.path.getsize(fp)
|
|
rel = os.path.relpath(fp, pkg_path)
|
|
if f.endswith(('.mil', '.json', '.txt')):
|
|
print(f"\n--- {rel} ({sz} bytes) ---")
|
|
with open(fp) as fh:
|
|
print(fh.read()[:3000])
|
|
elif f.endswith('.bin'):
|
|
print(f"Binary: {rel} ({sz} bytes)")
|
|
elif f.endswith('.mlmodel') or f.endswith('.plist'):
|
|
print(f"\n--- {rel} ({sz} bytes) ---")
|
|
try:
|
|
with open(fp) as fh:
|
|
print(fh.read()[:1000])
|
|
except:
|
|
print(f" (binary plist)")
|
|
else:
|
|
print(f"File: {rel} ({sz} bytes)")
|
|
|
|
print("\nDone. Use the extracted MIL text to fix the Objective-C ANE runtime.")
|