iOS와 Android에서의 LLM 추론 기법 — Apple MLX, Core ML, MediaPipe, Qualcomm AI Engine, 그리고 모바일 AI 앱 개발 패턴을 다룹니다.
5장에서 브라우저라는 범용 플랫폼 위에서의 LLM 추론을 살펴보았습니다. 브라우저 추론은 접근성이 뛰어나지만, 네이티브 API에 직접 접근할 수 없다는 구조적 한계가 있었습니다. 이번 장에서는 한 단계 더 내려가, iOS와 Android 네이티브 환경에서 LLM을 실행하는 방법을 다룹니다. 모바일 디바이스는 Neural Engine, NPU 등 전용 가속기를 탑재하고 있어, 이를 활용하면 브라우저 대비 훨씬 효율적인 추론이 가능합니다.
모바일 디바이스에서의 AI 추론은 데스크톱과 근본적으로 다른 제약 조건 아래에서 이루어집니다.
**통합 메모리 아키텍처(UMA)**는 CPU, GPU, NPU가 동일한 물리 메모리를 공유하는 구조입니다. iPhone 15 Pro의 경우 8GB, Galaxy S24 Ultra의 경우 12GB의 통합 메모리를 가집니다. 이 메모리를 OS, 앱, 그리고 AI 모델이 함께 사용해야 하므로, 실제로 모델에 할당 가능한 메모리는 총 용량의 50-60% 수준입니다.
**열 제약(Thermal Throttling)**도 중요한 고려사항입니다. 모바일 기기는 능동적 냉각 장치가 없어, 지속적인 고부하 연산 시 성능이 급격히 저하됩니다. LLM 추론처럼 수십 초간 연속으로 GPU/NPU를 사용하는 작업에서는 이 제약이 체감됩니다.
배터리 소모 역시 무시할 수 없습니다. 사용자 경험 관점에서, AI 기능 하나가 배터리를 급격히 소모한다면 해당 기능의 채택률은 낮아질 수밖에 없습니다.
Core ML은 Apple이 제공하는 온디바이스 머신러닝 프레임워크입니다. iOS, iPadOS, macOS에서 통합적으로 동작하며, Apple Neural Engine(ANE), GPU, CPU를 자동으로 선택하여 추론을 실행합니다.
import CoreML
import NaturalLanguage
class OnDeviceLLM {
private var model: MLModel?
func loadModel() async throws {
let config = MLModelConfiguration()
config.computeUnits = .all // ANE + GPU + CPU 자동 선택
// 컴파일된 Core ML 모델 로딩
let modelURL = Bundle.main.url(
forResource: "Phi3Mini4K",
withExtension: "mlmodelc"
)!
self.model = try await MLModel.load(
contentsOf: modelURL,
configuration: config
)
}
func generate(prompt: String, maxTokens: Int = 256) async throws -> String {
guard let model = self.model else {
throw LLMError.modelNotLoaded
}
var tokens = tokenize(prompt)
var output = ""
for _ in 0..<maxTokens {
let input = try MLDictionaryFeatureProvider(
dictionary: ["input_ids": MLMultiArray(tokens)]
)
let prediction = try await model.prediction(from: input)
let nextToken = argmax(prediction.featureValue(for: "logits")!)
if nextToken == eosTokenId { break }
tokens.append(nextToken)
output += decode(nextToken)
}
return output
}
}Core ML 모델을 만들기 위해서는 PyTorch 모델을 coremltools로 변환해야 합니다.
import coremltools as ct
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("microsoft/Phi-3-mini-4k-instruct")
# Core ML 변환 (4비트 양자화 적용)
mlmodel = ct.convert(
model,
convert_to="mlprogram",
minimum_deployment_target=ct.target.iOS18,
compute_precision=ct.precision.FLOAT16,
)
# 양자화 적용
op_config = ct.optimize.coreml.OpLinearQuantizerConfig(
mode="linear_symmetric",
dtype="int4",
granularity="per_block",
block_size=32,
)
config = ct.optimize.coreml.OptimizationConfig(global_config=op_config)
mlmodel_quantized = ct.optimize.coreml.linear_quantize_weights(mlmodel, config)
mlmodel_quantized.save("Phi3Mini4K.mlpackage")Apple은 iOS 18부터 Core ML에 4비트 양자화 지원을 추가했습니다. 이를 통해 3B 파라미터 모델을 약 2GB 미만의 크기로 변환하여, iPhone에서도 실용적인 수준의 LLM 추론이 가능해졌습니다.
MLX는 Apple이 오픈소스로 공개한 머신러닝 프레임워크로, Apple Silicon에 최적화되어 있습니다. NumPy와 유사한 API를 제공하면서도, 통합 메모리 아키텍처를 최대한 활용하여 CPU-GPU 간 메모리 복사 없이 연산을 수행합니다.
import mlx.core as mx
from mlx_lm import load, generate
# 4비트 양자화된 모델 로딩
model, tokenizer = load("mlx-community/Llama-3.1-8B-Instruct-4bit")
# 텍스트 생성
response = generate(
model,
tokenizer,
prompt="모바일 AI의 미래에 대해 설명해주세요.",
max_tokens=512,
temp=0.7,
)
print(response)MLX는 현재 macOS에서만 동작하며, iOS 지원은 아직 공식적으로 제공되지 않습니다. 하지만 MLX의 설계 원칙과 Apple Silicon 최적화 기술은 향후 iOS 온디바이스 AI의 기반이 될 것으로 예상됩니다.
3장에서 다룬 llama.cpp는 크로스 플랫폼 지원 덕분에 iOS와 Android에서도 실행 가능합니다. Metal(iOS)과 Vulkan(Android) 백엔드를 통해 모바일 GPU 가속도 지원합니다.
# iOS용 llama.cpp 빌드 (Metal 지원)
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
mkdir build-ios && cd build-ios
cmake .. \
-G Xcode \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_OSX_DEPLOYMENT_TARGET=17.0 \
-DLLAMA_METAL=ON \
-DLLAMA_METAL_EMBED_LIBRARY=ON \
-DBUILD_SHARED_LIBS=OFFclass LlamaCppWrapper {
// JNI를 통한 llama.cpp 연동
external fun loadModel(modelPath: String, nGpuLayers: Int): Long
external fun generate(contextPtr: Long, prompt: String, maxTokens: Int): String
external fun freeModel(contextPtr: Long)
companion object {
init {
System.loadLibrary("llama-android")
}
}
fun runInference(modelPath: String, prompt: String): String {
// Vulkan GPU 가속 레이어 수 설정
val ctx = loadModel(modelPath, nGpuLayers = 99)
val result = generate(ctx, prompt, maxTokens = 256)
freeModel(ctx)
return result
}
}MediaPipe LLM Inference API는 Google이 제공하는 크로스 플랫폼 온디바이스 LLM 추론 솔루션입니다. Android, iOS, 웹을 모두 지원하며, Gemma 모델 계열과의 통합이 긴밀합니다.
import com.google.mediapipe.tasks.genai.llminference.LlmInference
class MediaPipeLLMService(private val context: Context) {
private var llmInference: LlmInference? = null
fun initialize() {
val options = LlmInference.LlmInferenceOptions.builder()
.setModelPath("/data/local/tmp/gemma-2b-it-gpu-int4.bin")
.setMaxTokens(1024)
.setTemperature(0.7f)
.setTopK(40)
.setResultListener { partialResult, done ->
// 스트리밍 결과 처리
onTokenGenerated(partialResult, done)
}
.build()
llmInference = LlmInference.createFromOptions(context, options)
}
fun generateResponse(prompt: String) {
llmInference?.generateResponseAsync(prompt)
}
}MediaPipe LLM Inference API는 현재 Gemma, Phi, Falcon, StableLM 등 제한된 모델 아키텍처만 지원합니다. 지원 모델 목록은 공식 문서에서 확인해야 하며, 임의의 모델을 변환하여 사용하는 것은 제한적입니다.
Qualcomm AI Hub은 Snapdragon 프로세서의 Hexagon NPU를 활용한 AI 추론을 지원하는 플랫폼입니다. 모델 최적화, 변환, 벤치마킹 도구를 제공하며, Snapdragon 기기에서 최적의 성능을 끌어내기 위한 프로파일링 기능도 포함되어 있습니다.
Qualcomm의 QNN(Qualcomm Neural Network) SDK를 통해 Hexagon NPU에 직접 접근할 수 있으며, AI Hub를 통해 클라우드에서 모델을 최적화한 뒤 디바이스로 배포하는 워크플로를 제공합니다.
| 프레임워크 | 플랫폼 | 가속기 | 지원 모델 | 양자화 | 성숙도 |
|---|---|---|---|---|---|
| Core ML | iOS/macOS | ANE + GPU | 변환 필요 | INT4/INT8 | 높음 |
| MLX | macOS | Apple Silicon | HF 호환 | INT4/INT8 | 중간 |
| llama.cpp | 전체 | Metal/Vulkan | GGUF | Q2-Q8 | 높음 |
| MediaPipe | Android/iOS/Web | GPU/NPU | 제한적 | INT4/INT8 | 중간 |
| Qualcomm AI Hub | Android (Snapdragon) | Hexagon NPU | 변환 필요 | INT4/INT8 | 중간 |
| Samsung On-Device | Galaxy (Exynos) | NPU | 제한적 | INT8 | 초기 |
모바일에서 LLM을 통합할 때 몇 가지 공통적인 개발 패턴이 있습니다.
하이브리드 전략은 가장 현실적인 접근 방식입니다. 간단한 요청은 온디바이스 소형 모델(1-3B)로 처리하고, 복잡한 요청은 서버의 대형 모델로 라우팅하는 방식입니다. 네트워크 상태, 배터리 잔량, 요청 복잡도를 종합적으로 판단하여 라우팅을 결정합니다.
점진적 로딩은 사용자 경험을 위한 필수 패턴입니다. 모델 로딩에 수 초가 소요될 수 있으므로, 앱 시작 시 백그라운드에서 모델을 미리 로딩하거나, 사용자가 AI 기능에 접근하기 직전에 로딩을 시작하는 전략이 필요합니다.
메모리 관리는 모바일 환경에서 특히 중요합니다. iOS의 경우 메모리 경고(Memory Warning)를 받으면 즉시 모델을 해제해야 하며, Android에서는 onTrimMemory 콜백에서 적절히 대응해야 합니다.
모바일 LLM 앱 개발 시, 모델 로딩 시간을 사용자에게 자연스럽게 숨기는 UX 설계가 중요합니다. 스플래시 화면 동안 모델을 로딩하거나, 첫 번째 응답 전에 타이핑 애니메이션을 보여주는 등의 기법을 활용합니다.
모바일 디바이스에서의 LLM 추론은 메모리, 열, 배터리라는 세 가지 제약 속에서 최적의 균형을 찾아야 하는 도전적인 영역입니다. 그러나 NPU의 발전, 양자화 기법의 진보, 그리고 효율적인 소형 모델의 등장으로 실용적인 모바일 AI가 빠르게 현실화되고 있습니다.
다음 7장에서는 한 단계 더 들어가, 이러한 모바일 기기와 엣지 디바이스에 탑재된 **전용 하드웨어 가속기(NPU, Neural Engine)**의 아키텍처와 성능 특성을 비교 분석합니다.
이 글이 도움이 되셨나요?
관련 주제 더 보기
온디바이스 AI를 위한 하드웨어 가속기 — Apple Neural Engine, Qualcomm NPU, NVIDIA Jetson, Intel NPU의 아키텍처와 성능 특성을 비교합니다.
WebGPU를 활용한 브라우저 내 LLM 추론의 원리, WebLLM과 MLC LLM의 아키텍처, 실전 구현, 그리고 브라우저 AI의 가능성과 한계를 다룹니다.
온디바이스 AI를 활용한 실전 애플리케이션 설계 패턴 — 하이브리드 추론, 오프라인 우선, 프라이버시 보존, 개인화 학습, 그리고 에지-클라우드 협업을 다룹니다.