Офлайн AI-асистент на iOS та Android: впроваджуємо Llama.cpp

Уявіть: AI-асистент у мобільному додатку працює без інтернету, всі дані залишаються на пристрої. Жодної передачі на сервер, жодних затримок мережі. Хмарні LLM вимагають постійного з'єднання, передають конфіденційні дані та створюють затримки. Для медицини або фінансів це неприйнятно. On-device рішен

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Офлайн AI-асистент на iOS та Android: впроваджуємо Llama.cpp
Складний
~2-4 тижні

Наші компетенції:

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    897
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    783
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1004
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    598

Уявіть: AI-асистент у мобільному додатку працює без інтернету, всі дані залишаються на пристрої. Жодної передачі на сервер, жодних затримок мережі. Хмарні LLM вимагають постійного з'єднання, передають конфіденційні дані та створюють затримки. Для медицини або фінансів це неприйнятно. On-device рішення вирішує ці проблеми, але потребує ретельної інтеграції під платформу. Ми впроваджуємо Llama.cpp — бібліотеку інференсу LLM на CPU/GPU — в iOS та Android додатки. Розберемо технічні деталі: від вибору моделі до боротьби з перегрівом.

Як вибрати модель для офлайн-асистента?

Llama.cpp працює з моделями у форматі GGUF. Популярні варіанти для мобіля:

Модель Квантування Розмір RAM Швидкість (iPhone 14)
Llama-3.2-1B Q4_K_M 0.8 ГБ ~1.2 ГБ 25–35 t/s
Llama-3.2-3B Q4_K_M 2.0 ГБ ~2.5 ГБ 10–15 t/s
Phi-3-mini-4k Q4_K_M 2.2 ГБ ~2.8 ГБ 8–12 t/s
Gemma-2-2B Q4_K_M 1.6 ГБ ~2.0 ГБ 12–18 t/s
Qwen2.5-1.5B Q4_K_M 1.0 ГБ ~1.4 ГБ 20–28 t/s

На iPhone SE 2nd gen (3 ГБ RAM) Llama-3.2-3B Q4 працює на межі — OOM можливий при довгих контекстах. Безпечний вибір для широкого парку пристроїв — моделі до 1.5–2 ГБ. В одному з проектів для фінансового додатку ми вибрали Llama-3.2-1B Q4_K_M, що дозволило вкластися в 1 ГБ пам'яті на iPhone SE. Швидкість генерації склала 25-30 t/s, що достатньо для відповідей на запитання. Тепловий троттлінг був зведений до мінімуму обмеженням контексту до 1024 токенів.

Проблеми та рішення при on-device LLM

Проблема Рішення
OOM при великому контексті Обмежити n_ctx до 1024–2048 токенів
Тепловий троттлінг Моніторинг thermalState, паузи між генераціями
Пошкоджений GGUF-файл Верифікація SHA256 після завантаження
Низька швидкість на старих пристроях Використовувати моделі 1B з квантуванням Q4

Як зібрати llama.cpp для iOS?

# Клонуємо репозиторій git clone https://github.com/ggerganov/llama.cpp cd llama.cpp # Збірка через CMake для iOS cmake -B build-ios \ -DCMAKE_TOOLCHAIN_FILE=ios.toolchain.cmake \ -DPLATFORM=OS64 \ # arm64 only -DLLAMA_METAL=ON \ # Metal GPU прискорення -DLLAMA_STATIC=ON cmake --build build-ios --config Release 

Результат — libllama.a статична бібліотека. Створюємо Swift Package з C-bridging header:

// llama_bridge.h #include "llama.h" // Обгортки для Swift-дружнього API void* llama_create_context(const char* model_path, int n_ctx, int n_gpu_layers); const char* llama_generate_token(void* ctx, const char* prompt); void llama_free_context(void* ctx); 

n_gpu_layers — кількість шарів, що вивантажуються на Metal GPU. Значення -1 означає всі шари на GPU. На iPhone 14 з 6 ГБ unified memory — ставте -1. На пристроях з 3 ГБ — експериментуйте: занадто багато шарів на GPU викликає OOM.

Swift-обгортка для стрімінгу токенів

import Foundation actor LlamaSession { private var context: OpaquePointer? private var model: OpaquePointer? func load(modelPath: String, contextSize: Int32 = 2048, gpuLayers: Int32 = -1) throws { var params = llama_model_default_params() params.n_gpu_layers = gpuLayers model = llama_load_model_from_file(modelPath, params) guard model != nil else { throw LlamaError.modelLoadFailed } var ctxParams = llama_context_default_params() ctxParams.n_ctx = UInt32(contextSize) ctxParams.n_batch = 512 context = llama_new_context_with_model(model, ctxParams) } func generate(prompt: String) -> AsyncThrowingStream<String, Error> { AsyncThrowingStream { continuation in Task.detached(priority: .userInitiated) { // Токенізація var tokens = [llama_token](repeating: 0, count: 4096) let nTokens = llama_tokenize(self.model, prompt, Int32(prompt.utf8.count), &tokens, 4096, true, false) // Інференс — по одному токену for i in 0..<nTokens { llama_batch_add(&batch, tokens[Int(i)], llama_pos(i), [0], false) } while true { llama_decode(self.context, batch) let nextToken = llama_sample_token_greedy(self.context, &candidates) if nextToken == llama_token_eos(self.model) { break } // Конвертація токена в рядок var buf = [Int8](repeating: 0, count: 64) llama_token_to_piece(self.model, nextToken, &buf, 64, 0, true) let piece = String(cString: buf) continuation.yield(piece) } continuation.finish() } } } } 

Стрімінг токенів через AsyncThrowingStream — користувач бачить текст по мірі генерації, не чекає всю відповідь. Це критично для UX: 10 токенів за секунду сприймається нормально, якщо текст з'являється поступово.

Чому теплові обмеження критичні?

Llama.cpp на iPhone при тривалій генерації розігріває пристрій. iOS throttling: при перегріві система знижує тактову частоту, швидкість генерації падає з 25 t/s до 8–10 t/s. Це не баг — поведінка системи.

Практичне рішення: обмежувати максимальний контекст (n_ctx) до 1024–2048 для коротких сесій. Між запитами — пауза. Моніторити ProcessInfo.processInfo.thermalState на iOS:

NotificationCenter.default.addObserver(forName: ProcessInfo.thermalStateDidChangeNotification, ...) { _ in let state = ProcessInfo.processInfo.thermalState if state == .critical || state == .serious { // Призупинити генерацію, повідомити користувача } } 

Типові помилки при інтеграції

  • Занадто великий контекст — вибирайте n_ctx ≤ 2048 для мобільних пристроїв.
  • Ігнорування теплових throttle — моніторте thermalState і робіть паузи.
  • Неправильна версія моделі — перевіряйте, що GGUF-файл сумісний з вашою збіркою llama.cpp.
  • Відсутність верифікації хешу — пошкоджені файли призводять до крашів.

Android: llama.cpp через NDK

// CMakeLists.txt в jni/ add_library(llama_jni SHARED llama_jni.cpp) target_link_libraries(llama_jni llama ggml) // Kotlin side class LlamaEngine { init { System.loadLibrary("llama_jni") } external fun loadModel(modelPath: String, nGpuLayers: Int): Long // повертає handle external fun generateNext(handle: Long, tokens: IntArray): String external fun freeModel(handle: Long) } 

На Android — Vulkan backend замість Metal: в CMakeLists включаємо LLAMA_VULKAN=ON. Підтримується на пристроях з Vulkan 1.1+, тобто практично все з Android 10+.

Проблема з Android: процес не має обмеження пам'яті як цілого пулу — система може вбити додаток (SIGKILL) при нестачі RAM без попередження. ComponentCallbacks2.onTrimMemory(TRIM_MEMORY_RUNNING_CRITICAL) — останній шанс звільнити контекст перед вбивством процесу.

Завантаження моделі: прогрес і верифікація

GGUF-файли важать 1–4 ГБ. Завантажуємо через URLSession (iOS) або WorkManager з DownloadManager (Android). Верифікація SHA256 обов'язкова: після завантаження обчислюємо хеш і порівнюємо з очікуваним з репозиторію на HuggingFace. Пошкоджений GGUF викликає краш при парсингу заголовка або пізніше при інференсі — краще зловити на верифікації.

Мобільна нейромережа працює швидше без затримок мережі, що особливо важливо для критичних за часом додатків. Економія коштів: повністю офлайн рішення виключає витрати на серверну інфраструктуру.

Що входить в інтеграцію

  1. Аналіз парку пристроїв і підбір моделі з оптимальним квантуванням
  2. Збірка llama.cpp під iOS (Metal) та/або Android (Vulkan)
  3. Розробка Swift/Kotlin обгортки з асинхронним стрімінгом токенів
  4. Реалізація завантаження моделей з прогресом і верифікацією SHA256
  5. UI чат-інтерфейсу з індикацією теплового стану
  6. Стрес-тестування на реальних пристроях і тонке налаштування контексту
  7. Документація з інтеграції та підтримка на етапі запуску

Терміни орієнтовно

Одна платформа, базовий чат-інтерфейс з вибраною моделлю — від 3 тижнів. Обидві платформи, кілька моделей на вибір, фонове завантаження, управління контекстом — від 7 тижнів. Вартість розраховується індивідуально.

Наш досвід — 5 років у мобільній розробці та більше 20 проектів з on-device ML. Ми гарантуємо працездатність рішення на цільових пристроях після тестування. Отримайте консультацію щодо вибору моделі та оцінки вашого проекту. Замовте інтеграцію та переконайтеся в перевагах офлайн AI-асистента.