Розробка AI-асистента на базі локальної моделі (On-Device) у мобільному додатку
On-device LLM—це не просто «працює без інтернету». Це архітектурне рішення: дані користувача ніколи не залишають пристрій. Для медичних щоденників, особистих записок, корпоративних документів на пристрої співробітника—це не фіча, це вимога. Технічно розв'язується на сучасних флагманах, але потребує ретельного підбору моделі та runtime під конкретні пристрої.
Що реально запустити на телефоні в 2024–2025
Границя можливого зсунулася з появою нових чипів. iPhone 15 Pro (A17 Pro, 8 ГБ RAM, Neural Engine 35 TOPS) та Samsung Galaxy S24 (Snapdragon 8 Gen 3, 12 ГБ RAM) запускають 3B-моделі у INT4 квантуванні зі швидкістю 15–30 токенів/сек—достатньо для асистента з потоковим виводом.
| Пристрій | RAM | Рекомендована модель | Токени/сек |
|---|---|---|---|
| iPhone 15 Pro / 16 | 8 ГБ | Llama 3.2 3B Q4_K_M | 20–30 |
| iPad Pro M4 | 16 ГБ | Llama 3.1 8B Q4_K_M | 15–25 |
| Samsung S24 Ultra | 12 ГБ | Phi-3 Mini Q4 | 25–35 |
| Бюджетний Android | 4–6 ГБ | Phi-3 Mini Q2 / Gemma 2B | 5–15 |
| Старі пристрої | 3 ГБ | Не рекомендується | — |
Спроба запустити 7B+ модель на телефоні з 4 ГБ RAM—гарантований OOM краш.
iOS: Core ML та Apple MLX
Apple пропонує два шляхи. Core ML—стабільна, підтримує iOS 16+, автоматично використовує Neural Engine. Модель конвертується через coremltools з PyTorch/GGUF. Розмір після конвертації Llama 3.2 3B у INT4—близько 1.8 ГБ.
import CoreML
class OnDeviceLLM {
private let model: MLModel
init() throws {
let config = MLModelConfiguration()
config.computeUnits = .all // CPU + GPU + Neural Engine
model = try LlamaModel(configuration: config).model
}
func generate(prompt: String) -> AsyncStream<String> {
AsyncStream { continuation in
Task.detached(priority: .userInitiated) {
// tokenize → autoregressive decode → yield tokens
let tokens = self.tokenize(prompt)
for _ in 0..<512 {
let nextToken = self.model.predictNextToken(tokens)
continuation.yield(self.detokenize(nextToken))
if nextToken == self.eosTokenId { break }
}
continuation.finish()
}
}
}
}
Apple MLX (Swift framework, iOS 16+)—зручніший API, але вимагає iOS 16+ і краще працює на пристроях з уніфікованою пам'яттю. Офіційні конвертовані моделі від Apple доступні на Hugging Face.
llama.cpp—найбільший вибір моделей у GGUF форматі, активно підтримується спільнотою. Інтеграція через C++ bridging header складніша, ніж Core ML, але дає доступ до будь-якої GGUF-моделі.
Android: TFLite, MediaPipe, ExecuTorch
На Android більше варіантів і менше єдиного стандарту.
MediaPipe LLM Inference API (Google)—найдозрілішим рішенням для Android. Підтримує Gemma 2B/7B, Phi-2, Llama 2, ExportedModels у TFLite форматі. Інтеграція через клас LlmInference:
val options = LlmInference.LlmInferenceOptions.builder()
.setModelPath("/data/local/tmp/gemma-2b-it-gpu-int4.bin")
.setMaxTokens(1024)
.setResultListener { partialResult, done ->
runOnUiThread { appendText(partialResult) }
}
.build()
val llmInference = LlmInference.createFromOptions(context, options)
llmInference.generateResponseAsync(prompt)
TFLite з кастомним LLM runner—гібкіше, але потребує більше роботи щодо інтеграції.
ExecuTorch (Meta)—офіційний runtime для Llama на Android, підтримує Llama 3.x прямо без конвертації. Компілюється через buck2, що нетривіально налаштовувати в Gradle-проекті.
Завантаження та оновлення моделі
Модель неможливо паковати в bundle додатку—1.5–3 ГБ одразу призводять до відхилення в App Store та відлякують користувачів великим розміром APK. Правильний підхід: перший запуск → пропозиція завантажити модель → фонове завантаження з прогрес-баром → верифікація контрольної суми.
На iOS: URLSession.downloadTask з backgroundConfiguration—завантаження продовжується при уходу в фон. Файл зберігається в Application Support (не Caches—там може бути видалено системою при нестачі місця).
На Android: DownloadManager або WorkManager з NetworkType.UNMETERED constraint—користувач не витратить мобільний трафік.
Оновлення моделі: сервер публікує маніфест з поточною версією та SHA-256 сумою. При запуску додатку перевірте маніфест, якщо версія змінилася—пропропоную оновити.
Тепло та батарея
Вивід на Neural Engine/GPU гріє пристрій. Для довгих генерацій (>200 токенів) потрібно моніторити тепловий стан через ProcessInfo.thermalState (iOS)—при .serious знижуйте n_threads або тимчасово перемикайтесь на CPU-only вивід. На Android—PowerManager.thermalStatus.
Споживання батареї: 3B модель на iPhone 15 Pro витрачає ~5–8% батареї на 100 запитів. Не потрібно попереджати користувачів—це менше, ніж потік відео.
Кошторис строків
Базовий on-device асистент (одна платформа, Core ML або MediaPipe)—4–5 тижнів. Кросс-платформа з управлінням завантаженням, оновленнями та тепловим моніторингом—8–12 тижнів.







