Перенос модели машинного обучения на Android: конвертация в TFLite

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

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Перенос модели машинного обучения на 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 примеров, покрывающий все крайние случаи.

Несовместимость операций — около 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 Средняя Высокая Средняя

Прямой путь из TF даёт минимальные расхождения. Путь через 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. Кастомная операция через 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 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 в месяц. Стоимость проекта рассчитывается индивидуально под вашу модель и требования.

Свяжитесь с нами для оценки вашей модели — мы проведём бесплатный аудит TFLite-совместимости. Закажите консультацию, чтобы оптимизировать модель под ваш целевой парк устройств.

AI и ML в мобильных приложениях: CoreML, TFLite и on-device модели

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

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

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

TensorFlow Lite — кросс-платформенная альтернатива для Android и Flutter. На 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 токенов/секунду.

Ограничения реальны: модели больше 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, логирует запросы, защищает ключ.

Что входит в работу (deliverables)

  • Обученная и квантизированная модель под целевое устройство (документация по метрикам)
  • 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 в ваше приложение под ключ. Закажите аудит существующего решения — бесплатно оценим потенциал экономии серверных затрат (в некоторых проектах экономия достигает $10k в месяц).