Оптимізація ML-моделей під Core ML для пристроїв Apple

Модель працює на сервері, а застосунку потрібна реакція тут і одразу — без очікування мережі. Ми виконуємо конвертацію моделі в Core ML під ключ: переносимо обчислення на пристрій, перевіряємо точність і віддаємо готову збірку. Застосунок відповідає помітно швидше, витрата заряду знижується, а поведінка моделі залишається передбачуваною на всьому парку пристроїв.
Часті запитання

Чому конвертація моделі в Core ML ламається на перевірці

Конвертація моделі в Core ML виглядає як один виклик конвертера, але помилка під час перенесення моделі майже ніколи не виникає на цьому кроці.

Перший бар'єр — непідтримувані операції: дослідницький прототип зазвичай містить шари, для яких у Apple немає прямого аналога, і конвертер або зупиняється, або мовчки підставляє спрощену заміну.

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

Другий бар'єр — розбіжність результатів. Під час перенесення змінюються обчислювальні типи: навчання йде на повній точності, на пристрої вмикається половинна, а з нею — інше округлення та порядок операцій.

Різниця, яка в тестовому середовищі виглядає третьою цифрою після коми, на виході перетворюється в інший клас або зміщену рамку. Тому перевірка на пристрої має йти не на одному вдалому прикладі, а на наборі еталонних відповідей, знятих до конвертації.

Третій бар'єр — умови реальної експлуатації. Пристрій обмежений за пам'яттю, нагрівається й скидає частоти, камера та мікрофон відбирають ресурси, застосунок згортають у фоні.

Модель, стабільна на стенді, в бою дає затримки та відмови; частина дефектів видна лише в логах на живих збірках.

Розбираємо, як це закривається: розбір графа на несумісні вузли, заміна їх еквівалентними, тести на паритет відповідей і профілювання на реальних моделях пристроїв.

Що дає оптимізація: швидкість, відгук, ресурси пристрою

Локальний запуск моделі змінює профіль застосунку сильніше, ніж здається на етапі прототипу. Обчислення йдуть на самому пристрої через Core ML, тому час відгуку перестає залежати від якості мережі: кадр або текст обробляється за частки секунди, а не після кола до сервера й назад.

Користувач бачить реакцію інтерфейсу відразу — на цьому рівні різниця між «працює» і «працює приємно» стає очевидною.

Окремо рахуємо витрату батареї. Неквантована модель на кожному кадрі навантажує обчислювач по максимуму, і пристрій нагрівається вже через кілька хвилин роботи.

Після конвертації та підбору типу обчислень (процесор, графіка, нейромодуль) навантаження лягає на профільний блок чипа, а заряд витрачається помітно рівномірніше за тієї ж якості відповіді.

Обсяг застосунку — третя метрика, яку видно у звітах магазину. Вага моделі входить у збірку й напряму впливає на частку скасованих встановлень: чим більший пакет, тим частіше користувач перериває завантаження.

Стиснення ваг і відмова від невикористовуваних шарів зменшують внесок моделі в розмір збірки в рази, а важкі гілки можна довантажувати на вимогу — вже після першого запуску.

Частина відмов при цьому зникає цілим класом. Зникають таймаути, мережеві помилки та недоступність сервісу на стороні сервера: сценарій працює офлайн — у метро, в літаку, на слабкому каналі.

Залишаються лише відмови, пов'язані з даними та пам'яттю пристрою: невідповідний вхід, рідкісний формат, нестача ресурсів на старих моделях — їх закриваємо перевірками та запасним шляхом обробки.

Варіанти конвертації: на пристрої, в хмарі або змішаний режим

Конвертація моделі в Core ML формально дає один артефакт, але виконуватися він може в трьох різних режимах — і це різні архітектурні рішення, а не перемикач у налаштуваннях.

Режим визначає, де живуть ваги, як оновлюється модель після донавчання та які вимоги висуваються до пам'яті й живлення пристрою.

Режим Коли підходить Обмеження
Локальний запуск Персональні дані не повинні покидати пристрій, потрібен відгук без мережі, аудиторія на актуальній лінійці Розмір моделі впирається в доступну пам'ять; важкі сценарії гріють корпус і витрачають батарею; оновлення лише разом із релізом застосунку
Хмарний запуск Важкі обчислення, рідкісні дорогі операції, потрібна зміна моделі без випуску нової збірки Потрібна мережа, відгук залежить від каналу зв'язку, дані йдуть на сервер
Змішаний режим Часті легкі операції — на пристрої, важкі — на сервері Дорожче в розробці: дві гілки обчислень, синхронізація версій, єдина схема попередньої обробки даних

Вибір режиму виконання починається не з моделі, а з обмежень продукту: чутливість даних, допустима затримка відгуку, вимоги до приватності.

Далі ми рахуємо бюджет пам'яті й нагріву для цільової лінійки пристроїв і лише після цього вирішуємо, що виносити на сервер, а що залишати локально.

Етапи роботи: аудит, схема, збірка, перевірка, передача

Будь-яка оптимізація починається з замірів, а не з перезбирання моделі: без цифр за часом відгуку, пам'яттю та нагрівом незрозуміло, де вузьке місце — у графі обчислень, у вагах чи в тому, як застосунок звертається до моделі. Тому робота йде за фіксованими етапами, і на кожному залишається артефакт, який можна перевірити.

Як виглядає робота за кроками

  1. Аудит поточного рішення — розбираємо, як модель навчалася і в якому вигляді її віддає команда, які шари не переносяться напряму і де можлива втрата точності.
  2. Профілювання на цільових пристроях — знімаємо час відгуку, споживання пам'яті та нагрів на реальних телефонах і планшетах, а не на тестовому стенді.
  3. Схема перетворення — фіксуємо, які операції замінюємо в графі, де квантуємо ваги і який запас за точністю вважаємо допустимим.
  4. Конвертація моделі в Core ML — збираємо пакет, перевіряємо підтримку операцій і звіряємо виходи з вихідною моделлю на контрольному наборі прикладів.
  5. Збірка під пристрій — компонуємо модель із застосунком, обираємо режим прискорення та перевіряємо холодний старт.
  6. Перевірка на реальних сценаріях — проганяємо рідкісні та шумні вхідні дані, дивимося поведінку при нестачі пам'яті та перемиканні між застосунками.
  7. Приймання результату — порівнюємо метрики до і після за однією методикою, передаємо конфігурації, інструкції зі збірки та звіт, а при розбіжності відкочуємося на попередню збірку.

Артефакти проєкту: конфігурації, схеми, регламенти, документація

Конвертація моделі в Core ML — лише верхній шар роботи.

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

  • Конфігурації збірки — як модель і обв'язка збираються під потрібну версію системи та розрядність пристрою, з зафіксованими залежностями: повторна збірка дає той самий результат.
  • Схеми обробки даних — попередня обробка, нормалізація та постобробка виходів, із зазначенням точок виклику моделі в застосунку.
  • Правила версіонування — як нумеруються ваги й конфігурації, що вважається несумісною зміною і як версія моделі пов'язується з версією застосунку.
  • Регламент оновлення — покроковий випуск нової версії: прогін на контрольному наборі, перевірка метрик, умови відкату на попередню збірку.
  • Документація по моделі — входи й виходи, обмеження за розміром і часом відгуку, відомі слабкі місця та метрики приймання.
  • Контрольний набір і тести — фіксовані приклади входів з очікуваними результатами, щоб побачити розбіжність до викату.
  • Схема інтеграції — точки виклику, обробка помилок і поведінка при відмові моделі в застосунку.

Комплект лежить у репозиторії замовника поруч із кодом, тому оновлення моделі залишається звичайною інженерною задачею, а не окремим проєктом з нами.

Приклад із практики: прискорення роботи застосунку після оптимізації

Проєкт — мобільний сервіс розпізнавання об'єктів на фото: користувач знімає кадр і чекає результат. Спочатку модель рахувалася на серверній стороні — кадр ішов на обробку й повертався по мережі.

На тестовому стенді схема виглядала робочою, але на живих користувачах впиралася в два місця: затримку відгуку та втрати при нестабільному зв'язку.

Де саме втрачали

Кожен запит проходив повне коло: стиснення кадру, відправлення, черга на обробку, зворотний шлях. У пікові години черга зростала, і відгук розтягувався з 0,8 до 2,5 секунди — користувач встигав закрити застосунок.

На мобільній мережі частина запитів обривалася на середині: близько 6,5% операцій закінчувалися неуспіхом. Це клас відмов, який на серверній стороні не лікувався — причина була в каналі, а не в самій моделі.

Що змінили

Виведення моделі перенесли на сам пристрій: конвертували мережу в Core ML, стиснули ваги, знизили точність обчислень там, де це не впливало на розпізнавання, попередню обробку кадру винесли в окремий потік. Кадр більше не покидає пристрій — зникли і черга, і мережеве коло.

Відгук скоротився у 8-9 разів, з 0,8 до 0,09 секунди. Частка неуспішних операцій впала до 0,4%, розмір моделі на пристрої зменшився з 240 до 70 МБ, а навантаження на серверний контур знизилося настільки, що його потужність перестали нарощувати в міру зростання аудиторії.

Якість розпізнавання на контрольній вибірці при цьому не просіла — це перевіряли окремим прогоном до викату.

Що робити, якщо застосунок уже використовує інше середовище виконання?

Переписувати застосунок повністю не потрібно: середовище виконання — це шар виведення моделі, а не бізнес-логіка. Екрани, робота з камерою та зберігання даних залишаються незмінними, змінюється лише те, що стоїть за викликом «отримати передбачення».

Обсяг робіт залежить від того, наскільки вихідна модель спирається на можливості попереднього середовища.

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

Перехід без переписування тримається на адаптері виклику: вхідні та вихідні тензори приводяться до попередніх типів, решту коду не чіпаємо.

Донавчання потрібне, коли частину операцій цільове середовище не підтримує напряму: їх замінюють еквівалентними й доучують модель на тих самих даних, щоб повернути вихідну якість.

Повторне навчання та перегляд архітектури — для моделей, зав'язаних на серверні особливості: динамічні форми входу, нестандартні перетворення ознак.

Варіант Коли підходить Обмеження
Перезбирання готової моделі Стандартні шари, ваги без змін Не проходять рідкісні оператори
Донавчання Частину операцій замінено еквівалентними Потрібна навчальна вибірка та прогін перевірки
Повторне навчання Архітектура зав'язана на серверне середовище Довше, потребує звірки метрик з поточною версією
Перегляд архітектури Модель цілком переїжджає на пристрій Змінюються вимоги до пам'яті та розміру збірки

Порядок один: спочатку вимірюємо розбіжність виходів на контрольному наборі, і лише при виході за поріг ідемо в донавчання або перезбирання. Так перехід укладається в дні й не потребує переписування застосунку.

Обмеження, сумісність і вимоги до даних

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

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

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

Якщо вибірки збиралися різними способами, просідання після конвертації в Core ML виявиться наслідком даних, а не оптимізації — це видно на розборі, а не після релізу.

Які операції не переносяться на пристрій?

Динамічні форми тензорів, нестандартні шари уваги, власні оператори. Їх або виражають через підтримувані, або залишають на серверній стороні — рішення приймаємо за заміром якості та часу відгуку.

Як перевіряється якість після оптимізації?

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

Що з пристроями попередніх поколінь?

Збираємо матрицю сумісності: на яких поколіннях і версіях системи модель працює, де вмикається резервний шлях. Для слабких пристроїв заздалегідь готуємо полегшену гілку, щоб застосунок не втрачав функціональність.

Обговоримо задачу: що потрібно для оцінки термінів

Термін оцінки щодо перенесення моделі на пристрій визначається не її розміром, а числом шарів, які не мають штатного відображення в Core ML, і обсягом попередньої обробки вхідних даних. Чим раніше ми бачимо архітектуру та живі приклади, тим менше в плані запасу на невідомість. Нижче — що достатньо надіслати, щоб ми повернулися з планом робіт, а не з широким діапазоном.

  • Архітектура та ваги навченої моделі: стек навчання, скрипт збірки графа, чекпойнт, список нестандартних операцій.
  • Набір реальних вхідних даних з очікуваними відповідями — 100–300 прикладів вистачає, щоб зловити розбіжність числових результатів після конвертації.
  • Метрики приймання: частка правильних відповідей, допустима розбіжність з вихідною моделлю, вимоги до часу відгуку та витрати батареї.
  • Сценарій роботи на пристрої: повністю локальне виведення, довантаження оновлених ваг або гібрид із зверненням до сервера.
  • Обмеження: підтримувані версії системи, парк пристроїв, розмір застосунку, робота без мережі.
  • Доступи: репозиторій, середовище збірки, тестовий парк пристроїв, облікові записи для публікації.
  • Вимоги до приватності: які дані не повинні покидати пристрій.

Повертаємося з планом робіт: етапи, зміст кожного, точки приймання та те, що вважаємо результатом. Перший етап — пілотний: переносимо одну модель, заміряємо якість і швидкість на живих пристроях, фіксуємо розбіжності.

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

Напрямки AI-розробки

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

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1543
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1374
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142