Інтеграція On-Device LLM (MLC LLM) для офлайн AI-асистента у мобільному застосунку

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Інтеграція On-Device LLM (MLC LLM) для офлайн AI-асистента у мобільному застосунку
Складний
~2-4 тижні
Часті запитання

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

Етапи розробки

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

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Інтеграція локальної LLM (MLC LLM) для офлайн AI-помічника в мобільному додатку

MLC LLM (Machine Learning Compilation LLM) — проект від команди TVM, яка компілює мовні моделі безпосередньо для конкретних апаратних цілей. На відміну від llama.cpp, який працює через універсальний C++ backend, MLC генерує оптимізований Metal-код для iPhone або Vulkan для Android на час компіляції. Це забезпечує помітне прискорення — особливо на Apple Silicon.

Як MLC відрізняється від Llama.cpp

Llama.cpp інтерпретує GGUF-графи під час виконання, використовуючи Metal через загальний шлях. MLC LLM використовує AOT (Ahead-Of-Time) компіляцію: Python-скрипти генерують .metal/.vulkan шейдери, специфічні для кожної моделі та пристрою. Ціна довшої підготовки — більш ефективні шейдери.

На iPhone 14 Pro з Llama-3.2-3B Q4: llama.cpp — 10–14 t/s, MLC LLM — 16–22 t/s. Різниця помітна.

Компіляція моделей для iOS

# Встановлення mlc-llm
pip install mlc-llm

# Компіляція моделі для iPhone (Metal)
mlc_llm convert_weight \
    ./Llama-3.2-3B-Instruct/ \
    --quantization q4f16_1 \
    --output mlc-llm-weights/

mlc_llm gen_config \
    ./Llama-3.2-3B-Instruct/ \
    --quantization q4f16_1 \
    --conv-template llama-3 \
    --output mlc-llm-config/

mlc_llm compile \
    mlc-llm-config/mlc-chat-config.json \
    --device iphone \
    --output dist/libs/Llama-3.2-3B-Instruct-q4f16_1-iphone.tar

Результат — архів з .dylib та Metal шейдерами. Вбудуйте в Xcode проект.

Для Android використовуйте той же процес з --device android:

mlc_llm compile \
    mlc-llm-config/mlc-chat-config.json \
    --device android \
    --output dist/libs/Llama-3.2-3B-Instruct-q4f16_1-android.tar

iOS SDK: Swift інтеграція

MLC LLM надає офіційний Swift Package — mlc-swift:

import MLCSwift

// Ініціалізація рушія
let engine = MLCEngine()

// Завантаження моделі (асинхронно)
try await engine.reload(
    modelPath: Bundle.main.path(forResource: "Llama-3.2-3B", ofType: nil)!,
    modelLib: "Llama-3.2-3B-Instruct-q4f16_1-iphone"  // ім'я .dylib без розширення
)

// Потокова передача через async/await
let messages: [ChatCompletionMessage] = [
    .init(role: .system, content: "You are a helpful assistant."),
    .init(role: .user, content: "Пояснити, що таке RAG у машинному навчанні")
]

let request = ChatCompletionRequest(messages: messages, stream: true)

for await chunk in try await engine.chat.completions.create(request) {
    if let delta = chunk.choices.first?.delta.content {
        // Додайте дельту до UI в реальному часі
        await MainActor.run { self.responseText += delta }
    }
}

API тісно повторює OpenAI Chat Completions API — спрощує повторне використання коду між серверною та локальною реалізаціями.

Android SDK: Kotlin інтеграція

import ai.mlc.mlcllm.MLCEngine

class LLMViewModel(application: Application) : AndroidViewModel(application) {
    private val engine = MLCEngine()

    suspend fun loadModel(modelPath: String, modelLib: String) {
        engine.reload(modelPath, modelLib)
    }

    fun chat(userMessage: String): Flow<String> = flow {
        val messages = listOf(
            ChatCompletionMessage(role = MessageRole.user, content = userMessage)
        )
        val request = ChatCompletionRequest(messages = messages, stream = true)

        engine.chat.completions.create(request).collect { chunk ->
            chunk.choices.firstOrNull()?.delta?.content?.let { delta ->
                emit(delta)
            }
        }
    }.flowOn(Dispatchers.IO)
}

flowOn(Dispatchers.IO) — інференс не повинен блокувати основний потік. UI підписується на Flow через collectAsState() в Compose або launchWhenResumed в Fragment.

Управління пам'яттю моделей

Одна модель в пам'яті одночасно — правило для мобільних пристроїв. Вивантаження:

await engine.unload()
// Явне вивантаження звільняє Metal буфери та пам'ять GPU
// Після цього можна завантажити іншу модель

На iOS пам'ять Metal — це окремий пул від системної RAM, але спільний з іншими додатками. Якщо користувач перейде до важкого додатку (гра, камера), система може примусово витіснити ресурси Metal — моделі потрібно перезавантажити.

// Обробка витіснення ресурсів Metal
NotificationCenter.default.addObserver(
    forName: .MLCEngineModelUnloaded,  // або власний механізм виявлення
    object: nil, queue: .main
) { [weak self] _ in
    Task { try await self?.engine.reload(...) }
}

Завантаження та управління моделями

Ваги моделей не вбудовуються в app bundle (обмеження App Store — 4 ГБ на весь пакет, ваги можуть бути 2–4 ГБ). Завантажуйте при першому запуску або на вимогу:

// Фонове завантаження через URLSession
func downloadModel(from url: URL, modelName: String) async throws {
    let destinationURL = Self.modelsDirectory.appendingPathComponent(modelName)
    guard !FileManager.default.fileExists(atPath: destinationURL.path) else { return }

    let (tempURL, _) = try await URLSession.shared.download(from: url)
    try FileManager.default.moveItem(at: tempURL, to: destinationURL)
}

static var modelsDirectory: URL {
    FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]
        .appendingPathComponent("MLCModels")
}

applicationSupportDirectory — правильне місце для великих даних додатку (не Documents, видимих користувачам в Files.app).

Коли використовувати MLC vs Llama.cpp

MLC LLM переважно коли: максимальна швидкість на конкретних пристроях важлива, цільові пристрої відомі (компіляція для конкретних архітектур), використовуються офіційні моделі HuggingFace (Llama, Phi, Gemma, Mistral).

Llama.cpp переважно коли: потрібна гнучкість у виборі квантування, моделі приходять у форматі GGUF від партнерів, потрібна підтримка старих пристроїв, потрібне користувацьке семплування (beam search, специфічні параметри температури).

Процес

Вибір моделі для задачі та діапазону пристроїв → компіляція для цілей iOS/Android → інтеграція SDK → реалізація чат-інтерфейсу з асинхронною потоковою передачею → конвеєр завантаження ваг → тестування теплових обмежень.

Орієнтири за часом

Одна платформа, одна модель, базовий чат — 3–5 тижнів. Обидві платформи, перемикання між кількома моделями, система управління вагами — 7–11 тижнів.