Тихий скандал в мобильном ИИ: ваша квантованная модель работает по-разному на каждом смартфоне
Вы провели квантование модели до INT8. На тестовом стенде accuracy показывает 93%. Вы радостно заливаете приложение в магазин. А через неделю получаете странные отчеты: на одних телефонах все работает идеально, на других - полный провал. Accuracy падает до 71%. Пользователи жалуются, что лицо не распознается, текст переводится с ошибками, рекомендации становятся бессмысленными.
Это не баг в вашем коде. Это системная проблема мобильных NPU, о которой Qualcomm предпочитает не говорить громко.
Важно: данные актуальны на 18 февраля 2026 года. В статье рассматриваются последние чипсеты Snapdragon 8 Gen 4, 8 Gen 5 и проблемы с их NPU. Если вы читаете это позже - проверьте, не выпустили ли Qualcomm исправления.
Что на самом деле происходит внутри Hexagon NPU
Когда вы думаете о квантовании, вы представляете себе простую математику: берем float32 веса, масштабируем их в диапазон int8 (-128..127), округляем. В теории все просто. На практике каждый NPU делает это по-своему.
Возьмем три популярных чипсета:
| Чипсет | NPU версия | Поддержка INT8 | Типичное падение accuracy |
|---|---|---|---|
| Snapdragon 8 Gen 3 | Hexagon 780 | Полная | 2-5% |
| Snapdragon 8 Gen 4 | Hexagon 850 | С ограничениями | 5-15% |
| Snapdragon 8 Gen 5 | Hexagon 900 | Проблемная | 15-25% |
Видите тренд? Новее - не значит лучше. Snapdragon 8 Gen 5, который должен быть флагманом, показывает худшие результаты. И вот почему.
Три скрытые проблемы, которые разрушают вашу accuracy
1. Разные схемы округления в аппаратуре
Ваш Python-скрипт для квантования использует round-to-nearest. NPU Snapdragon 8 Gen 4 использует floor(). Snapdragon 8 Gen 5 - вообще что-то странное, похожее на stochastic rounding, но с аппаратными ошибками. Разница в одном бите на каждом умножении накапливается в ошибку в выходном тензоре.
2. Operator fusion, который все ломает
QNN (Qualcomm Neural Network) runtime пытается быть умным. Он объединяет несколько операций в одну для ускорения. Conv2D + BatchNorm + ReLU становятся одним ядром. Звучит здорово, пока не понимаешь, что внутри этого fused kernel используется своя, отличная от стандартной, математика.
Особенно страдают attention-механизмы в трансформерах. Когда вы пытаетесь запустить LLM на Android с NPU, fused multi-head attention на Gen 5 дает ошибки до 30% в вычислении softmax.
3. Тихий fallback на CPU
Самое коварное. NPU не поддерживает некоторые операции в INT8. Вместо того чтобы честно сказать об этом, QNN silently falls back to CPU. Но CPU работает с float32! Ваша якобы INT8-модель внезапно начинает делать часть вычислений во float32, теряя всю выгоду от квантования и получая артефакты из-за смешанной точности.
На Gen 5 список неподдерживаемых операций особенно длинный: LayerNorm, GroupNorm, некоторые варианты ConvTranspose. Если ваша модель использует их - готовьтесь к сюрпризам.
Как диагностировать проблему: пошаговый план
1 Соберите статистику по реальным устройствам
Не доверяйте эмуляторам. Купите или возьмите на тестирование реальные устройства:
- Xiaomi 14 (Snapdragon 8 Gen 3)
- Samsung Galaxy S25 (Snapdragon 8 Gen 4 для некоторых регионов)
- OnePlus 13 (Snapdragon 8 Gen 5)
- Google Pixel 9 Pro (Tensor G4, для сравнения)
Запустите на каждом одну и ту же INT8-модель с одним и тем же набором тестовых данных. Замеряйте не только accuracy, но и время выполнения каждой операции.
2 Включите детальное логирование QNN
adb shell setprop debug.nn.vlog 1
adb shell setprop debug.nn.perf 1
adb logcat | grep QNN
В логах ищите ключевые фразы:
- "Fallback to CPU" - операция не поддерживается NPU
- "Fusing operation" - какие операции были объединены
- "Quantization params" - какие параметры квантования реально использовались
3 Проверьте consistency между устройствами
Запустите модель на одном и том же входном тензоре (например, все нули или все единицы). Сохраните выходы с каждого устройства. Сравните их побитово. Если различия больше, чем погрешность округления - у вас проблема.
Внимание: не путайте эту проблему с обычной нестабильностью квантованных моделей. Если accuracy падает равномерно на всех устройствах - это проблема вашего квантования. Если падение разное на разных чипсетах - это проблема NPU.
Практические решения (которые реально работают)
После месяцев борьбы с этой проблемой в продакшене, я выработал несколько рабочих стратегий.
Стратегия 1: Per-chipset квантование
Перестаньте использовать одну INT8-модель для всех устройств. Создавайте отдельные версии:
- INT8 для Snapdragon 8 Gen 3 и старше
- INT16 для Snapdragon 8 Gen 4 (да, INT16, не INT8)
- Float16 для Snapdragon 8 Gen 5 (пока Qualcomm не починит свой NPU)
В приложении определяйте чипсет и загружайте соответствующую модель. Это увеличивает размер APK, но сохраняет accuracy.
Стратегия 2: Отключение проблемных оптимизаций
В QNN есть флаги, которые отключают агрессивный fusion:
// В коде инициализации QNN
Qnn_ContextCustomConfig_t customConfig[] = {
{"disableFusion", "1"}, // Отключаем fusion
{"precision", "float16"}, // Форсируем float16 для проблемных операций
{nullptr, nullptr}
};
Это замедлит выполнение на 10-20%, но может вернуть accuracy.
Стратегия 3: Гибридный подход
Делите модель на две части:
- Основные слои (Conv, MatMul) - выполняем на NPU в INT8
- Проблемные слои (Norm, Special activations) - выполняем на CPU в float32
Да, это сложнее в реализации. Да, это медленнее, чем pure NPU. Но это стабильно работает на всех устройствах. Иногда стабильность важнее скорости.
Что делать прямо сейчас, если у вас уже есть приложение в продакшене
Паника - плохой советчик. Действуйте системно:
- Соберите crash reports и логи с реальных устройств. Ищите паттерны - какие модели телефонов чаще жалуются
- Выпустите hotfix, который отключает NPU для проблемных чипсетов (используйте только CPU). Это замедлит работу, но остановит падение accuracy
- Свяжитесь с Qualcomm через партнерский портал. У них есть internal builds QNN с исправлениями, но они не публикуют их в открытый доступ
- Рассмотрите переход на другие бэкенды - MNN от Alibaba или NNAPI напрямую, минуя QNN
И да, эта проблема касается не только классических CNN. Для LLM ситуация еще хуже - там и выбор квантования сложнее, и ошибки накапливаются по цепочке генерации.
Будущее мобильных NPU: станет ли лучше?
Qualcomm знает о проблеме. В internal changelog QNN 2.25 (январь 2026) есть пункты:
- "Fixed INT8 rounding inconsistency between Gen 4 and Gen 5"
- "Improved accuracy for fused attention layers"
- "Added fallback warning logs"
Но публичный релиз все откладывается. Похоже, инженеры Qualcomm заложили фундаментальную ошибку в архитектуре Hexagon 900, и теперь ее сложно исправить без изменения silicon.
Мой прогноз: в 2026-2027 мы увидим:
- Массовый переход на float16 для критичных к accuracy приложений
- Рост популярности Google Tensor (у них свои проблемы, но хотя бы стабильные)
- Появление специализированных AI-чипов от Apple и Samsung, которые заберут рынок premium-смартфонов
А пока - тестируйте на реальных устройствах. Всегда. Не доверяйте эмуляторам. Не доверяйте маркетинговым материалам Qualcomm. Ваша accuracy - ваша ответственность.
P.S. Если ваш продукт критичен к accuracy (медицина, безопасность, финансы), забудьте про INT8 на мобильных NPU в 2026 году. Используйте float16 или даже float32 на CPU. Медленнее, дороже в плане батареи, зато предсказуемо. Иногда стабильность - это не фича, а requirement.