-
Apple Neural Engine(ANE) 의 내부 구조를 직접 분석해 CoreML을 우회하고 하드웨어에 직접 접근하는 방법을 구현
- CoreML의 추상화 계층을 제거하고
_ANEClient API를 통해 모델 컴파일·로드·실행을 직접 수행
-
MIL(Machine Learning Intermediate Language) 과 E5 바이너리 포맷을 분석해 ANE가 고정 연산 프리미티브 기반의 그래프 실행 엔진임을 확인
-
IOSurface 공유 메모리를 이용해 GPU↔ANE 간 제로카피 데이터 전송 가능성을 입증
- 이 연구는 M4 ANE의 실제 성능 측정과 학습 가능성을 탐구하는 3부작 중 첫 번째로, Apple 비공개 하드웨어에 대한 최초의 직접 제어 사례로 의미 있음
인간–AI 협업을 통한 리버스 엔지니어링 접근
- 연구는 인간 연구자와 Anthropic의 Claude Opus 4.6이 협력해 진행
- 인간이 탐색 방향을 제시하고, AI가 데이터 분석과 코드 작성 수행
- 목표는 “Apple Neural Engine 위에서 직접 모델을 학습시킬 수 있는가”라는 질문에서 출발
- Apple은 ANE의 ISA, 내부 구조, 직접 프로그래밍 인터페이스를 공개하지 않음
- CoreML을 통해서만 접근 가능하며, 이는 하드웨어 동작을 이해하기 어렵게 만듦
- 이에 따라 CoreML에서 IOKit 커널 드라이버까지 전체 소프트웨어 스택을 역추적하고, ANE를 직접 제어하는 코드 경로를 확보
Neural Engine의 구조
- ANE는 GPU나 CPU가 아닌 그래프 실행 엔진(graph execution engine) 형태
- 컴파일된 신경망 그래프 전체를 하나의 원자적 연산으로 실행
- M4 칩의 ANE(코드명 H16G)는 16코어, 127개 요청 큐 깊이, 독립 DVFS 제어, 유휴 시 0mW 전력 차단 기능 보유
- Apple은 A11(2017)에서 2코어 ANE를 처음 도입한 이후 세대별로 확장
기존 연구와 차별점
- 기존 공개 자료:
-
Matthijs Hollemans의 ANE 동작 문서 및 성능 분석
-
mdaiter/ane의 초기 리버스 엔지니어링 샘플
-
Asahi Linux의 리버스 엔지니어드 Linux 드라이버
-
apple/ml-ane-transformers의 공식 트랜스포머 최적화 코드
- 이번 연구의 독자적 성과:
- CoreML 없이 직접
_ANEClient API 접근 성공
-
MIL 인메모리 컴파일 경로 해독
-
CoreML 오버헤드 제거 후 실제 처리량 측정
-
추론 전용 하드웨어에서 모델 학습 수행
분석 방법론
-
클래스 탐색:
dyld_info -objc 명령으로 AppleNeuralEngine.framework 내부 클래스 목록 추출
-
메서드 스위즐링: CoreML 호출을 가로채 비공개 프레임워크 호출 경로 확인
-
바이너리 분석: 컴파일된 E5 번들을 해독해 프로그램 포맷 파악
-
스케일링 분석: 행렬 크기·그래프 깊이·채널 수를 변화시켜 하드웨어 토폴로지 추론
- 결과적으로
_ANEClient, _ANEModel, _ANERequest, _ANEIOSurfaceObject, _ANEInMemoryModel 등 40개 이상의 비공개 클래스 발견
CoreML 우회: _ANEClient 직접 접근
-
_ANEClient를 통해 모델 컴파일 → 로드 → 평가의 전체 파이프라인을 직접 제어 가능
- CoreML은 단순히 이 과정을 감싸는 편의 계층에 불과함
- ANE는 최대 127개의 동시 평가 요청(queue depth) 을 지원, 고처리량 스트리밍 추론에 최적화
-
IOSurface 기반 I/O 버퍼를 사용해 GPU와 ANE 간 공유 메모리 전송 가능
MIL: ANE 입력 언어
- CoreML은 ONNX나 protobuf 대신 MIL(Machine Learning Intermediate Language) 을 사용
- 정적 단일 할당(SSA) 기반, 타입·형상 명시
- 예시 코드에서
matmul 연산이 명확히 표현됨
- 텐서 레이아웃은 NCDHW + Interleave 형식으로
[Batch, Channels, Depth, Height, Width] 구조
E5 바이너리 포맷
- MIL 프로그램은 E5 FlatBuffer 바이너리로 컴파일
- 1024×1024 행렬 곱: 2,688바이트, 128×128 행렬 곱: 2,680바이트
- 코드 크기가 거의 동일 → 행렬 연산 알고리듬이 아닌 파라미터화된 구성 정보만 포함
- 이는 ANE가 고정된 연산 프리미티브(Conv, MatMul, Elementwise 등) 를 조합해 그래프를 실행함을 의미
인메모리 컴파일 경로
-
_ANEInMemoryModelDescriptor를 이용해 디스크 접근 없이 메모리 내에서 MIL 컴파일 가능
- 주요 문제점 및 해결:
-
milText는 NSString이 아닌 NSData(UTF-8 바이트) 필요
-
weights는 이름–데이터 매핑 딕셔너리 형태
- 내부적으로 임시 디렉터리 접근 필요 → 쓰기 권한 확보 필수
- Apple 내부 코드에서
Desctiptor 오타 발견
하드웨어 프로파일
-
IOKit 분석 결과, ANE는 독립적인 전력·클록 관리(DVFS) 채널 보유
-
ANE_ADCLK_TRIG, ANE_PPT_TRIG 등 다양한 하드웨어/소프트웨어 트리거 존재
-
ANECompiler.framework에서 확인된 지원 연산 중 Conv가 핵심 연산 프리미티브
- Part 2에서 1×1 Conv를 MatMul로 변환 시 3배 성능 향상 확인 예정
IOSurface 프로토콜
- 모든 데이터 입출력은 IOSurface 공유 메모리 객체를 통해 수행
- GPU 텍스처 공유 메커니즘과 동일
-
GPU↔ANE 제로카피 파이프라인 구성 가능성 존재
컴파일 캐시 구조
- ANE 컴파일러는 E5 바이너리를 디스크에 캐시
- 경로:
~/Library/Caches/.../com.apple.e5rt.e5bundlecache/.../H16G.bundle/
- 첫 컴파일 20–40ms, 캐시 히트 시 즉시 실행
- 추론에는 유리하지만, 학습 시 가중치 변경으로 재컴파일 필요
미탐색 영역
- 아직 분석되지 않은 클래스:
-
_ANEChainingRequest — 여러 모델을 단일 디스패치로 연결 가능성
-
_ANESharedEvents, _ANESharedSignalEvent, _ANESharedWaitEvent — GPU↔ANE 동기화용 펜스/시그널
-
_ANEPerformanceStats — 하드웨어 성능 카운터 가능성
-
_ANEVirtualClient — 멀티프로세스 가상화 접근 가능성
- 미확인 항목:
- ANE 코어 마이크로아키텍처 및 ISA
- 그래프 내 연산의 코어 할당 방식
- 클록 주파수 및 SRAM 구조
향후 계획
-
Part 2: 행렬 곱 스케일링, SRAM 병목, Conv와 MatMul 성능 비교, Apple의 “38 TOPS” 수치 검증
-
Part 3: ANE에서 신경망 학습 수행
- 모든 코드는 github.com/maderix/ANE의
ane/ 디렉터리에 공개
- 테스트 환경: M4 Mac Mini, macOS 15.x