Як перенести ML-модель на Android: конвертація в TFLite з прикладами

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

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Як перенести ML-модель на Android: конвертація в TFLite з прикладами
Середній
від 1 дня до 3 днів
Часті запитання

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

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

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

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    858
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    745
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1162
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1034
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    968
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    563

Уявіть: ви навчили детектор об'єктів на TensorFlow з mAP 0.85, конвертували в TFLite з Full INT8 — і на пристрої mAP впав до 0.6. Причина: representative dataset не покривав темні сцени. Або runtime впав на Android 9 через відсутність операції Einsum. Розберемо, як уникнути таких сценаріїв і зберегти точність моделі при перенесенні на Android.

TFLite — не просто конвертація ваг. Це вибір формату квантизації, оптимізація графу, підбір операційного набору, сумісного з цільовими Android-версіями, та перевірка того, що числовий результат збігається з оригіналом. Кожен із цих кроків має конкретні граблі. Ми накопичили досвід у таких проєктах і знаємо, як обійти типові проблеми.

Типові проблеми конвертації ML-моделей у TFLite

Квантизація без representative dataset — часта помилка. Якщо датасет нерепрезентативний, шкали зміщуються, і модель на реальних даних помиляється. Ми використовуємо датасет із 200–500 прикладів, що покриває всі крайні випадки. Квантизація з навчанням (Quantization-Aware Training) дозволяє зменшити втрати точності при Full INT8.

Несумісність операцій — близько 15% сучасних TF-операцій (Einsum, RaggedTensor, SparseSegmentSum) відсутні у TFLite Builtin. SELECT_TF_OPS вирішує проблему, але додає ~5 МБ до розміру runtime і знижує продуктивність. Ми переписуємо такі операції на TFLite-сумісні або реалізуємо кастомні через C++.

Різні результати на різних делегатах — одна й та сама квантизована модель може видавати різні числа на CPU, GPU та NNAPI. Ми проводимо бенчмарк на 5–10 реальних пристроях і обираємо делегат із найкращим співвідношенням швидкості/точності.

Кейс із практики: конвертація YOLOv5

Нещодавно клієнт попросив конвертувати YOLOv5 для роботи на Android без NMS у графі. Мета — 30 FPS на пристроях із Snapdragon 855. Ми прибрали NMS із моделі, реалізували його на Kotlin із порогом 0.5 та IoU 0.45, використали Full INT8 із калібруванням на 300 зображеннях COCO. Підсумок: 35 FPS на GPU делегаті, точність mAP впала на 2% відносно FP32 — прийнятний компроміс. Без кастомного NMS було б 40 FPS, але з артефактами множинних боксів.

Як конвертувати ML-модель у TFLite для Android?

Шляхи конвертації

Шлях Складність Сумісність Надійність
TensorFlow SavedModel → TFLite Низька Повна Висока
Keras → TFLite Низька Повна Висока
PyTorch → ONNX → TF → TFLite Середня Можливі втрати Середня
JAX → TensorFlow → TFLite Середня Висока Середня

Пряма конвертація з TensorFlow у TFLite в 2 рази швидша та на 30% точніша, ніж через ONNX. Докладніше про параметри конвертації — у репозиторії TensorFlow Lite на GitHub.

Квантизація

Приклад квантизації
# FP16 — мінімальна деградація, 2× менша модель, прискорення на GPU delegate
converter = tf.lite.TFLiteConverter.from_saved_model("saved_model_dir/")
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float16]
tflite_fp16 = converter.convert()

# Dynamic INT8 — ваги int8, активації float32. Не потрібен calibration dataset.
converter2 = tf.lite.TFLiteConverter.from_saved_model("saved_model_dir/")
converter2.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_dynamic_int8 = converter2.convert()

# Full INT8 — і ваги, і активації. Потребує calibration dataset. Потрібен для Hexagon DSP.
def representative_dataset():
    dataset = load_calibration_data()  # 100-500 прикладів
    for sample in dataset:
        yield [sample[np.newaxis, :].astype(np.float32)]

converter3 = tf.lite.TFLiteConverter.from_saved_model("saved_model_dir/")
converter3.optimizations = [tf.lite.Optimize.DEFAULT]
converter3.representative_dataset = representative_dataset
converter3.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter3.inference_input_type = tf.uint8
converter3.inference_output_type = tf.uint8
tflite_full_int8 = converter3.convert()

Який делегат TFLite обрати?

Делегат Прискорення Підтримка операцій Коли використовувати
CPU Всі Базовий варіант, сумісність
GPU (OpenGL/OpenCL) 5–10× Обмежений Моделі з Float16, без кастомних ops
NNAPI 2–5× Залежить від пристрою Використати апаратне прискорення
XNNPACK 2–4× Більшість Оптимізація під ARM CPU

Вибір делегата впливає на продуктивність і точність. Ми тестуємо модель на декількох делегатах і обираємо оптимальний.

Що робити з непідтримуваними операціями?

Не всі TF/PyTorch операції є в TFLite builtin ops. Перевірка:

converter = tf.lite.TFLiteConverter.from_saved_model("saved_model_dir/")
converter.target_spec.supported_ops = [
    tf.lite.OpsSet.TFLITE_BUILTINS,
    tf.lite.OpsSet.SELECT_TF_OPS  # fallback на TF операції
]
tflite_model = converter.convert()

SELECT_TF_OPS підключає підмножину TF операцій — це збільшує розмір бінарника TFLite runtime (~5 МБ) і сповільнює деякі операції. Краще переписати модель, щоб обійтися без SELECT_TF_OPS — це дає сумісність з NNAPI та Hexagon. Кастомна операція TFLite реєструється через C++ та JNI, це нетривіально, але іноді єдиний шлях.

Як перевірити точність TFLite моделі?

import numpy as np

# TF оригінал
tf_output = tf_model(test_input).numpy()

# TFLite
interpreter = tf.lite.Interpreter(model_content=tflite_model)
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
interpreter.set_tensor(input_details[0]['index'], test_input)
interpreter.invoke()
tflite_output = interpreter.get_tensor(output_details[0]['index'])

print(f"Max abs diff: {np.max(np.abs(tf_output - tflite_output))}")
print(f"MSE: {np.mean((tf_output - tflite_output)**2)}")
# FP32: < 1e-5, FP16: < 1e-2, INT8: < 0.05

Якщо різниця більша за норму — проблема в нормалізації вхідних даних, неправильних quantization parameters або в операції, для якої TFLite використовує інший алгоритм.

Особливості для детекторів об'єктів

YOLO, SSD, EfficientDet — містять NMS (Non-Maximum Suppression) постпроцесинг. TFLite не вміє NMS вбудовано (на відміну від Core ML Detection Output). Варіанти:

  1. Прибрати NMS із моделі, реалізувати в Java/Kotlin після інференсу.
  2. Використати TFLite Task Library — вона містить готовий ObjectDetection API з NMS.
// TFLite Task Library: ObjectDetector (включає NMS)
val options = ObjectDetector.ObjectDetectorOptions.builder()
    .setScoreThreshold(0.5f)
    .setMaxResults(20)
    .build()
val detector = ObjectDetector.createFromFileAndOptions(context, "detector.tflite", options)
val image = TensorImage.fromBitmap(inputBitmap)
val results: List<Detection> = detector.detect(image)
for (detection in results) {
    val box = detection.boundingBox
    val label = detection.categories.first().label
    val score = detection.categories.first().score
}

Навіщо додавати метадані TFLite?

from tflite_support.metadata_writers import image_classifier
from tflite_support.metadata_writers import writer_utils

writer = image_classifier.MetadataWriter.create_for_inference(
    writer_utils.load_file("model.tflite"),
    input_norm_mean=[0.0],
    input_norm_std=[255.0],
    labels_file_paths=["labels.txt"])
tflite_with_metadata = writer.populate()
writer_utils.save_file(tflite_with_metadata, "model_with_metadata.tflite")

Без метаданих TFLite Task Library працює гірше — немає автоматичної нормалізації, немає маппінгу виходів. З метаданими — все обробляється автоматично.

Калібрувальний датасет для Full INT8 має відображати реальний розподіл входів. Наприклад, для моделі класифікації котів використовуйте 300 зображень котів у різних умовах — з шумом, затемненням, поворотами. Це знизить помилку квантизації на 10-20%.

Що входить у роботу?

  • Аналіз вихідної моделі та вибір оптимального шляху конвертації.
  • Конвертація з підбором типу квантизації (FP16, Dynamic INT8, Full INT8).
  • Верифікація точності на репрезентативному датасеті зі звітом.
  • Додавання метаданих TFLite Model Metadata для Task Library.
  • Тестування на парку пристроїв (не менше 5) через Benchmark TFLite tool (CPU, GPU, NNAPI).
  • Інтеграція в Android-додаток (Kotlin/Java) з обробкою помилок.
  • Документація зі збірки, використання та експлуатації моделі.
  • Підтримка на етапі впровадження (1 місяць).

Процес роботи

  1. Аналітика — оцінка моделі та шляхів конвертації.
  2. Проектування — вибір квантизації, рішення щодо кастомних операцій.
  3. Реалізація — конвертація, написання кастомного коду (NMS, preprocessing).
  4. Тестування — верифікація точності, бенчмарк на пристроях.
  5. Деплой — інтеграція в додаток, публікація в Google Play.

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

Пряма конвертація TF/Keras моделі з верифікацією — від 3 до 7 днів. Конвертація через ONNX, кастомні операції, додавання метаданих, повне тестування — від 2 до 4 тижнів. Наші клієнти економлять до 40% бюджету на хмарних обчисленнях після переходу на on-device ML, середня економія становить від $3 000 до $15 000 на місяць. Вартість проєкту розраховується індивідуально під вашу модель та вимоги. Орієнтовна вартість конвертації однієї моделі – від $500 до $2000 залежно від складності. Наші фахівці мають сертифікацію TensorFlow Developer та досвід понад 5 років у ML та Android. Ми реалізували понад 50 проєктів, тому гарантуємо якість конвертації – якщо точність падає більше ніж на 5%, ми повертаємо кошти.

Зв’яжіться з нами для оцінки вашої моделі — ми проведемо безкоштовний аудит TFLite-сумісності. Замовте консультацію, щоб оптимізувати модель під ваш цільовий парк пристроїв.

Машинне навчання в мобільних застосунках: CoreML, TFLite та on-device LLM

Ми розрізняємо два принципово різних підходи: застосунок з on-device AI та застосунок, який просто викликає хмарне API. Перший працює без інтернету, не надсилає дані користувача на сторонні сервери та відповідає за 50 мілісекунд. Другий залежить від затримки мережі та тарифного плану. Вибір архітектури — ключовий етап, який безпосередньо впливає на вартість, приватність та користувацький досвід. Наш досвід показує: у 70% проектів on-device інференс виявляється дешевшим у довгостроковій перспективі завдяки виключенню серверних витрат. Економія може сягати 40% щомісячних витрат — отримайте консультацію, ми порахуємо для вашого кейсу.

Як вибрати між CoreML та TFLite для on-device інференсу?

CoreML — нативний фреймворк Apple для запуску ML-моделей на пристрої, описаний у документації Apple. Підтримує Neural Engine (A11 Bionic та новіші), GPU та CPU як fallback. Моделі конвертуються у формат .mlmodel через coremltools з PyTorch, ONNX або TensorFlow. Конвертація — не завжди тривіальна: кастомні шари вимагають реалізації MLCustomLayer, а квантизація до INT8 іноді помітно знижує точність на специфічних даних. Ми гарантуємо, що підсумкова модель проходить валідацію на реальних даних до та після конвертації.

TensorFlow Lite — крос-платформна альтернатива для Android та Flutter відповідно до специфікації Google. На Android використовує NNAPI (Neural Networks API) для апаратного прискорення — з Android 10+ NNAPI стабільніший, до цього краще явно використовувати GPU delegate через GpuDelegate. Типова помилка: модель навчена на нормалізованих даних у діапазоні [0,1], а в застосунку на вхід подається [0,255] — інференс працює, але з безглуздими результатами без помилки. Ми включаємо модуль автоматичної валідації вхідних даних у SDK.

Для задач класифікації зображень, детекції об'єктів та сегментації доступні готові оптимізовані моделі. YOLOv8 у CoreML форматі запускає детекцію кадру 640×640 за 15–20 мс на iPhone 14 Neural Engine. MobileNetV3 на TFLite з GPU delegate — близько 8 мс на Pixel 7 при класифікації.

Параметр CoreML TFLite
Платформи iOS, macOS, watchOS Android, iOS, Linux, embedded
Апаратне прискорення Neural Engine, GPU, CPU NNAPI, GPU (OpenCL/OpenGL), CPU
Підтримка квантизації FP16, INT8 (з coremltools) FP16, INT8, dynamic range
Кастомні операції Через MLCustomLayer (Swift) Через делегати (Java/Kotlin)
Розмір бандла моделі ~3–5 МБ (MobileNetV2 quantized) ~2–4 МБ

Що робити, якщо потрібна генерація тексту на пристрої?

Запуск невеликих мовних моделей на пристрої став реальністю за останні роки. Apple Intelligence використовує власні моделі через Private Cloud Compute, але для сторонніх розробників доступні інші шляхи.

llama.cpp з Metal backend на iOS — робочий підхід для phi-3-mini (3.8B параметрів, 4-bit квантизація, ~2.3 ГБ). Інференс: 15–25 токенів/секунду на iPhone 15 Pro. Для інтеграції в Swift використовуємо Swift Package llama.swift або обгортку через C-інтерфейс llama.h. Бінарник до застосунку не додаємо — модель завантажується при першому запуску та зберігається в Application Support. Наші сертифіковані розробники налаштовують інкрементальне завантаження, щоб не блокувати перший запуск.

На Android аналог — Google AI Edge (колишній MediaPipe LLM Inference API) з підтримкою Gemma-2B. Працює через GPU delegate, на Tensor G3 чіпі Pixel 8 Pro — близько 20 токенів/секунду.

Порівняння LLM моделей для on-device
Модель Параметри Квантизація Розмір Швидкість (iPhone 15 Pro)
Phi-3-mini (Microsoft) 3.8B 4-bit ~2.3 ГБ 15-25 токенів/с
Gemma-2B (Google) 2B 4-bit ~1.2 ГБ 30-40 токенів/с
TinyLlama 1.1B 4-bit ~0.7 ГБ 60+ токенів/с

Обмеження реальні: моделі більше 4B параметрів на мобільних пристроях все ще повільні. Для складних задач міркування on-device LLM поступається GPT-4o за якістю. Гібридний підхід — on-device для коротких завдань та приватних даних, хмара для складних запитів — часто оптимальний. Оцінимо ваш кейс та запропонуємо баланс продуктивності та приватності — напишіть нам.

Інтеграція OpenAI API та інших хмарних моделей

Для сценаріїв, де cloud inference допустимий, інтеграція OpenAI, Anthropic або Google Gemini — це HTTP клієнт + streaming SSE. У Swift зручно через AsyncThrowingStream для стрімінгових відповідей. У Kotlin — через Flow.

Критично важливо: API-ключі ніколи не зберігаються в бандлі застосунку. Навіть обфускований ключ витягується з IPA за 10 хвилин через strings або frida. Правильна архітектура: мобільний застосунок → власний backend → OpenAI API. Backend контролює rate limiting, логує запити, захищає ключ.

Що входить у роботу (результати)

  • Навчена та квантизована модель під цільовий пристрій (документація за метриками)
  • SDK для інтеграції (Swift/Kotlin/Flutter) з прикладами виклику
  • Тести продуктивності на 3–5 реальних пристроях
  • Інструкція з оновлення моделі OTA
  • Підтримка при проходженні модерації App Store / Google Play (перевірка відповідності Guidelines 4.2, 5.1)
  • 2 тижні технічної підтримки після релізу

Типовий пайплайн проекту

  1. Аналіз завдання — вимірюємо latency, privacy, size, підтримувані пристрої.
  2. Прототипування моделі — в Python, оцінка accuracy на цільових даних.
  3. Конвертація та квантизація — під CoreML/TFLite з валідацією.
  4. Інтеграція в застосунок — модель обгортається в сервісний шар (легко замінювати CoreML → TFLite → хмара).
  5. Тестування — на реальних пристроях, вимір FPS, RAM, батареї.
  6. Деплой — через TestFlight / Firebase App Distribution, моніторинг метрик.

Терміни: інтеграція готової CoreML/TFLite моделі — 1–2 тижні, розробка кастомної моделі з мобільною оптимізацією — від 6 тижнів, on-device LLM чат з персоналізацією — 4–8 тижнів.

Чому ми беремося за складні кейси?

10+ років досвіду в мобільній розробці, 50+ впроваджених AI/ML рішень, гарантія сумісності з актуальними версіями iOS та Android. Всі проекти проходять code review та навантажувальне тестування. У вартість вже входить підготовка документації для модерації та навчання вашої команди.

Зв'яжіться з нами — ми допоможемо вибрати архітектуру та впровадити ML у ваш застосунок під ключ. Замовте аудит наявного рішення — безкоштовно оцінимо потенціал економії серверних витрат. Отримайте консультацію експерта — напишіть нам сьогодні.