M4 Apple Neural Engine 내부 탐구, Part 1: 리버스 엔지니어링

3 weeks ago 5

  • 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

Read Entire Article