Оптимизация 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
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139