Оптимізація 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. Вимагає калібрувального набору даних (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)

# Калібрування: запустіть набір даних калібрування
with torch.no_grad():
    for batch in calibration_loader:
        model(batch)

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

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

Квантизація TFLite: повна цілочисельна

# Конвертація з повною 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

# Генератор калібрування — критичний для точності 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()

Повні 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-бітна лінійна квантизація ваг
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 квантизація — окремий коефіцієнт масштабу для кожного вихідного каналу в шарах згортки. Істотно точніша ніж per_tensor (один масштаб на весь шар), дещо повільніше. Зазвичай виправдана для CNN.

Аналіз чутливих шарів

Не всі шари однаково переносять квантизацію. Перший та останній шари мережі, плюс attention шари в трансформерах — часто найбільш чутливі. Інструмент: аналіз чутливості за шаром.

# Перевірте деградацію точності при квантизації кожного шару окремо
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 — це змішана точність квантизації. Квантизуйте решту до INT8. 5–10% "важких" шарів залишаються в FP32, модель втрачає лише 20–30% обсягу замість 75%, точність зберігається.

Верифікація: що та як перевіряти

Після квантизації обов'язкові перевірки:

  1. Точність на тестовому наборі даних — порівняйте top-1/top-5 точність з оригіналом. Прийнятна деградація: FP16 — <0.5%, INT8 — <2%. Якщо більше — перейдіть до QAT або змішаної точності.

  2. Числова похибка — порівняйте виходи на однакових входах між float та квантизованою моделлю. MSE < 0.01 зазвичай прийнятна.

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

  4. Краш-тест — різні входи, граничні випадки (чорне зображення, дуже яскраве, незвичайне співвідношення сторін). INT8 моделі іноді переповнюються на екстремальних входах.

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

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) → калібрування → аналіз чутливих шарів → змішана точність при потребі → верифікація точності → замери швидкості на цільових пристроях.

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

PTQ для однієї моделі з верифікацією — 1–2 тижні. QAT з повним циклом перенавчання та тестування — 3–6 тижнів залежно від розміру набору даних.