안녕하세요, 옵트에이아이 박성재입니다.
지난 글에서 Core AI 변환 스택의 설계를 ANEMLL과 비교하며 살펴봤습니다. 이번 글은 그 후속편으로, 실제 iPhone에서 Core AI로 모델을 돌려본 실측 기록입니다. Qwen3-0.6B를 export부터 디바이스 측정까지 전 과정을 거쳐, Core AI의 두 엔진(GPU/ANE)과 기존 런타임(MLX, CoreML-LLM)을 같은 조건에서 비교했습니다.
1. 준비물: iOS 27 beta와 Xcode 27 beta
iPhone에서 Core AI를 테스트하려면 다음이 필요합니다.
- iOS 27 beta (디바이스)
- Xcode 27 beta (Mac)
현재 글을 작성하는 날짜 기준에서 정식 버전은 26.x이므로, 기기를 백업한 뒤 27 beta로 업데이트해야 합니다. Core AI 프레임워크는 iOS 시뮬레이터 SDK에 포함되지 않으므로 실기기 측정이 필수입니다.
2. 핵심 전제: 연산 장치는 export shape이 결정한다
Core AI에서 가장 먼저 이해해야 할 지점입니다. iPhone에서 모델이 ANE 위에서 도는지 GPU 위에서 도는지는 런타임 플래그가 아니라 export 시점의 모델 shape이 결정합니다.
| Export | 명령 | Shape / 양자화 | 자동 선택되는 엔진 | 연산 장치 |
|---|---|---|---|---|
| 정적(static) | coreai.llm.export qwen3-0.6b --platform iOS | 고정 ctx · 4bit 팔레타이즈드 | static-shape | ANE |
| 동적(dynamic) | coreai.llm.export qwen3-0.6b --platform macOS | 동적 ctx · INT4 linear | coreai-pipelined | GPU |
지난 글에서 다룬 "iOS는 정적 shape + enumerated 특수화, macOS는 동적 shape"이라는 export 경로 분기가, 런타임에서는 곧 ANE 엔진과 GPU 엔진의 분기가 됩니다. 런타임의 EngineFactory가 번들 구조를 보고 엔진을 자동으로 선택하는 구조이기 때문에, 두 연산 장치를 비교하려면 두 개의 번들을 따로 만들어야 합니다. 이번 측정에서도 그렇게 진행했습니다.
3. 파이프라인: Export → AOT Compile → Assemble → Sideload → Measure
전체 흐름은 다섯 단계입니다.
Export (Mac, Python) : HF 모델 → Core AI MLIR IR (.aimodel)
AOT compile (Mac, aimodelc) : IR → 디바이스 GPU-arch용 .aimodelc ← iOS 전용 단계
Assemble (Mac, shell) : .aimodelc + tokenizer + metadata.json → 로드 가능한 번들
Sideload (Mac → iPhone)
Measure (iPhone, 앱)Apple이 공개한 coreai-models 저장소의 export 레시피를 그대로 사용합니다.
cd ~/code/coreai/coreai-models
# GPU용 (동적 shape, INT4) — coreai-pipelined GPU 엔진을 타게 됨
uv run coreai.llm.export qwen3-0.6b --platform macOS --output-name qwen3_0_6b_dynamic
# ANE용 (정적 shape, 팔레타이즈드 4bit) — static-shape ANE 엔진을 타게 됨
uv run coreai.llm.export qwen3-0.6b --platform iOS \
--compression 4bit_weight_palettized_group32 --output-name qwen3_0_6b_ios_pure4bit여기서 생성되는 .aimodel은 실행 바이너리가 아니라 IR입니다. macOS는 로드 시 JIT 컴파일이 가능하지만 iOS는 불가능합니다 — 다음 단계가 필요한 이유입니다.
export된 모델은 지난 글에서 다룬 4개의 entrypoint로 구성됩니다.
load_embeddings : embedding table을 한 번 로드
gather_embeddings : token id를 fp16 transformer_input으로 변환
prompt_opt : 긴 prompt chunk를 처리해 KV cache만 채움
extend : transformer forward + KV cache update + logits 생성iOS에서 IR을 그대로 로드하면 에러가 발생합니다. 디바이스마다 다른 GPU 아키텍처에 맞춰 미리 컴파일해야 합니다.
xcrun coreai-build compile qwen3_0_6b_ios_pure4bit.aimodel \
--platform iOS --preferred-compute neural-engine --architecture h18p --output out/
# → out/qwen3_0_6b_ios_pure4bit.h18p.aimodelc--preferred-compute neural-engine→ ANE 번들,gpu→ GPU 번들--architecture h18p→ iPhone 17 Pro(A19 Pro)의 GPU 패밀리. 다른 기기는 해당 arch 코드로 다시 컴파일해야 합니다.
컴파일된 .aimodelc와 tokenizer, metadata.json을 한 폴더로 묶고, metadata.json의 assets.main을 device-arch 컴파일 파일명으로 패치합니다.
# bench_coreai_iphone.sh 의 assemble() 이 하는 일 (요약)
cp -R out/qwen3_0_6b_ios_pure4bit.h18p.aimodelc bundle/
cp -R tokenizer bundle/
# metadata.json 의 assets.main = "qwen3_0_6b_ios_pure4bit.h18p.aimodelc" 로 패치이 과정을 거치면 ANE용, GPU용 두 개의 번들이 만들어집니다.
벤치마크 앱을 devicectl로 실행해 측정합니다.
xcrun devicectl device process launch --terminate-existing --device <UDID> \
com.iosllmbenchmark.benchmarkapp -- \
--yardstick-autorun --runtime core-ai --model-id core-ai/qwen3-0.6b-gpu --task short-chat --runs 14. 결과: Qwen3-0.6B, iPhone 17 Pro
*Qwen3-0.6B decode throughput on iPhone 17 Pro (short-chat, cold ×3)*
| 엔진 | 연산 | Decode tok/s | TTFT (warm) | Peak RAM |
|---|---|---|---|---|
| Core AI GPU (pipelined) | GPU | 181 (cold 71) | ~26 ms | 524 MB |
| MLX | GPU | 112 | ~57 ms | 539 MB |
| Core AI ANE (static-shape) | ANE | 49 | ~63 ms | 1,166 MB |
| CoreML-LLM | ANE | 39 | ~548 ms | 184 MB (최소) |
5. 분석: 세 가지 관찰
첫째, Core AI GPU pipelined 엔진이 압도적입니다. decode 181 tok/s로 같은 GPU를 쓰는 MLX(112 tok/s) 대비 약 1.6배이며, TTFT도 ~26ms로 가장 짧습니다. 동적 shape + INT4 linear 조합의 coreai-pipelined 엔진이 현재 iPhone에서 가장 빠른 LLM 실행 경로였습니다.
둘째, cold와 warm의 격차가 큽니다. GPU 엔진은 cold 71 tok/s → warm 181 tok/s로 벌어지는데, 이는 Core AI가 첫 로드 시 수행하는 디바이스별 specialization의 영향으로 보입니다. 실서비스에서는 첫 실행 지연을 어떻게 다룰지가 UX 설계 포인트가 됩니다.
셋째, ANE 경로는 속도가 아니라 메모리 축의 선택지입니다. Core AI ANE는 49 tok/s로 GPU 대비 크게 느렸고 Peak RAM도 1,166MB로 가장 높았습니다. 반면 CoreML-LLM은 39 tok/s로 가장 느리지만 184MB라는 최소 메모리로 동작했습니다. 다만 TTFT ~548ms는 대화형 UX에는 부담스러운 수치입니다. 요약하면 현시점 iPhone 17 Pro에서의 선택지는 "속도가 필요하면 Core AI GPU, 메모리가 극단적으로 제약되면 CoreML-LLM"으로 정리되며, ANE 경로는 이번 측정 조건(0.6B, short-chat)에서는 두 축 모두에서 우위를 보이지 못했습니다.
6. 결론
Core AI에서 연산 장치의 선택은 export 시점에 이미 끝나 있습니다. shape과 양자화 구성이 엔진을 결정하고, iOS에서는 AOT 컴파일이라는 디바이스 아키텍처별 단계가 추가됩니다. 그리고 그 결과물인 coreai-pipelined GPU 엔진은 기존 온디바이스 런타임 대비 뚜렷한 성능 우위를 보였습니다.
이번 측정은 Qwen3-0.6B 단일 모델, iPhone 17 Pro 단일 기기, short-chat 태스크 기준입니다. 모델 크기(1.7B 이상)와 컨텍스트 길이에 따라 ANE/GPU의 우위가 달라질 수 있는 만큼, 다음 글에서는 측정 범위를 넓혀 다뤄보겠습니다. 많은 관심 부탁드립니다.
export가 산출하는 .aimodel은 실행 바이너리가 아닌 MLIR IR입니다. macOS는 로드 시 JIT 컴파일이 가능하지만 iOS는 불가능하므로, 타겟 기기의 GPU 아키텍처(h18p 등)에 맞춰 Mac에서 미리 컴파일한 .aimodelc가 필요합니다.
Core AI 런타임이 번들 구조(shape·양자화 구성)를 보고 static-shape(ANE) 또는 coreai-pipelined(GPU) 엔진을 자동으로 선택하는 컴포넌트입니다. 사용자가 런타임 플래그로 연산 장치를 지정하는 방식이 아닙니다.
요청 후 첫 토큰이 나오기까지의 지연 시간입니다. prefill 성능과 모델 로드 상태(cold/warm)의 영향을 함께 받습니다.
Core AI 모델이 첫 로드 시 현재 기기·OS 버전에 맞춰 최적화되는 과정입니다. cold 실행과 warm 실행의 성능 격차를 만드는 주요 요인입니다.
참고 자료
- OptAI Blog, "Core AI: 온디바이스 생성형 모델을 위한 변환 스택의 재설계" — 본 벤치마크의 전편
- apple/coreai-models — Core AI 공식 모델·export 레시피 저장소 (github.com/apple/coreai-models)
- Apple, "Integrate on-device AI models into your app using Core AI" — WWDC26 Session 326
