Оптимизация ML-модели (квантизация) для мобильного устройства

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

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Оптимизация ML-модели (квантизация) для мобильного устройства
Сложный
~3-5 дней
Часто задаваемые вопросы

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

Этапы разработки

Последние работы

  • 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

Оптимизация ML-модели (квантизация) для мобильного устройства

Квантизация — перевод весов модели из float32 в формат с меньшей разрядностью: float16, int8, int4. Модель ResNet-50 весит 98 МБ в FP32. После int8 квантизации — 25 МБ. Скорость инференса на мобильном CPU вырастает в 2–4× за счёт уменьшения объёма данных и использования целочисленных инструкций ARM NEON/SVE.

Но простая квантизация часто роняет точность сильнее, чем хотелось бы. Правильная квантизация — это подбор метода, анализ чувствительных слоёв и верификация деградации.

Типы квантизации и когда что применять

Post-Training Quantization (PTQ) — квантизуем уже обученную модель без дообучения. Два варианта:

  • Dynamic quantization — веса в int8, активации вычисляются в float32 в рантайме. Простая, не требует калибровочных данных. Хорошо работает для RNN/Transformer (BERT, LLM). Для CNN даёт меньший прирост.
  • Static quantization — и веса, и активации в int8. Требует calibration dataset (100–500 репрезентативных примеров). Быстрее dynamic, но нужна калибровка.

Quantization-Aware Training (QAT) — модель дообучается с «симулированной» квантизацией. Веса адаптируются к пониженной точности. Лучшее качество, но требует доступа к обучающему датасету и GPU-времени.

# PyTorch: static PTQ через torch.quantization
import torch
from torch.quantization import quantize_static, get_default_qconfig

model.eval()
model.qconfig = get_default_qconfig('fbgemm')  # x86; для ARM — 'qnnpack'
torch.quantization.prepare(model, inplace=True)

# Calibration: прогоняем calibration dataset
with torch.no_grad():
    for batch in calibration_loader:
        model(batch)

torch.quantization.convert(model, inplace=True)
# Теперь model содержит квантизованные слои

Для мобильного Android (ARM) — qconfig = 'qnnpack', не 'fbgemm'. Это меняет порядок квантизованных операций под QNNPACK backend, который использует ARM NEON инструкции.

TFLite квантизация: full integer

# Конвертация с full int8 (активации + веса)
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8

# Calibration generator — критично для точности static quantization
def representative_dataset():
    for sample in calibration_data[:500]:
        yield [sample.astype(np.float32)]

converter.representative_dataset = representative_dataset
tflite_model = converter.convert()

Full int8 модель работает на NNAPI и Hexagon DSP — там, где FP16 не поддерживается. На Snapdragon 778G через Hexagon — 5–8× быстрее CPU при правильной INT8 квантизации.

Core ML квантизация на iOS

import coremltools as ct
from coremltools.optimize.coreml import (
    OptimizationConfig,
    OpLinearQuantizerConfig,
    linearly_quantize_weights
)

# Загружаем уже конвертированную Core ML модель
mlmodel = ct.models.MLModel("model_fp32.mlpackage")

# Конфигурация: 8-bit линейная квантизация весов
config = OptimizationConfig(
    global_config=OpLinearQuantizerConfig(
        mode="linear_symmetric",
        dtype=np.int8,
        granularity="per_channel"  # per_channel точнее per_tensor для CNN
    )
)

compressed_model = linearly_quantize_weights(mlmodel, config)
compressed_model.save("model_int8.mlpackage")

per_channel квантизация — отдельный scale factor для каждого выходного канала свёрточного слоя. Значительно точнее per_tensor (один scale на весь слой), но чуть медленнее. Для CNN обычно оправдано.

Анализ чувствительных слоёв

Не все слои одинаково переносят квантизацию. Первый и последний слои сети, а также слои attention в трансформерах — часто самые чувствительные. Инструмент: per-layer sensitivity analysis.

# Проверяем деградацию точности при квантизации каждого слоя по отдельности
from torch.quantization.quantize_fx import prepare_fx, convert_fx

baseline_accuracy = evaluate(float_model, test_loader)

for layer_name in get_all_quantizable_layers(model):
    # Квантизуем только этот слой
    single_layer_model = quantize_single_layer(model, layer_name)
    layer_accuracy = evaluate(single_layer_model, test_loader)
    sensitivity = baseline_accuracy - layer_accuracy
    print(f"{layer_name}: sensitivity={sensitivity:.4f}")

Слои с высокой чувствительностью оставляем в FP32 — это mixed precision quantization. Остальные переводим в INT8. 5–10% «тяжёлых» слоёв остаются в FP32, модель теряет только 20–30% объёма вместо 75%, но точность сохраняется.

Верификация: что и как проверять

После квантизации обязательно:

  1. Точность на тестовом датасете — сравниваем top-1/top-5 accuracy с оригиналом. Допустимая деградация: FP16 — <0.5%, INT8 — <2%. Если больше — переходим к QAT или mixed precision.

  2. Числовая погрешность — на одинаковых входах сравниваем выходы float и quantized модели. MSE < 0.01 обычно приемлемо.

  3. Скорость на реальных устройствах — не на симуляторе. Xcode Instruments → Core ML Profiler для iOS, adb shell am instrument + TFLite Benchmark Tool для Android.

  4. Краш-тест — разные входы, edge cases (чёрное изображение, очень яркое, нестандартный aspect ratio). INT8 модели иногда overflow на экстремальных входах.

Практический кейс

Модель детекции объектов YOLOv8n в FP32 — 6.3 МБ, 45 мс на iPhone 13. После Core ML INT8 квантизации — 1.8 МБ, 12 мс. mAP упал с 37.3 до 36.1 — в пределах допустимого для большинства задач. На Snapdragon 8 Gen 1 через TFLite INT8 + NNAPI — 8 мс.

Процесс

Аудит исходной модели → выбор метода (PTQ/QAT, INT8/FP16) → калибровка → анализ чувствительных слоёв → mixed precision при необходимости → верификация точности → замеры скорости на целевых устройствах.

Ориентиры по срокам

PTQ для одной модели с верификацией — 1–2 недели. QAT с полным циклом дообучения и тестированием — 3–6 недель в зависимости от размера датасета.