Квантование может сделать ваши модели глубокого обучения меньше, быстрее и более энергоэффективными (Я уже писал об этом ранее).
Но этот процесс может привести к большой потере точности или не может улучшить скорость прогнозирования, если будет выполнен неправильно. Итак, я делюсь некоторыми практическими советами, как минимизировать потерю точности при сохранении хорошей скорости вывода. Эти пункты действительны как для квантования после обучения, так и для обучения с учетом квантования.
1. Не квантовать полную модель
Обычно это наиболее частая причина низкой точности в квантованных сетях. Почти во всех учебных пособиях и руководствах, доступных в Интернете, они, как правило, помогут вам квантовать полную модель. Это простой способ, но может привести к плохим результатам.
Лучше всего квантовать только определенные слои. Посмотрите на это изображение, показывающее размеры различных уровней сети на основе кодировщика-декодера:
Если вы проведете здесь квантование полной модели, вы получите неточную модель. Почему? Как вы можете видеть на изображении выше, некоторые слои очень маленькие (‹2 МБ). Информация в этих слоях уже очень плотная и, следовательно, имеет очень низкую избыточность. Если вы сожмете эти слои, вы потеряете информацию, полученную сетью, и, следовательно, точность упадет.
Как правило, следует оставлять следующие типы слоев с полной точностью:
- Очень маленькие слои.
- Слои в начале и конце сети.
- Слои соединены несколькими блоками. (Например, пропустить подключения).
Примечание. В PyTorch вам нужно выполнить два шага:
1. Используйте объекты класса
QuantStub()
для квантования входных тензоров только тех слоев, которые вы хотите квантовать, а затем деквантовайте выходные данные этого слоя с помощьюDeQuantStub()
.
2. Установите
qconfig
только для тех слоев, которые вы хотите квантовать, а не для всей модели. Например, вместоmodel.qconfig
используйтеmodel.en[0].conv[1].qconfig
, если вы хотите квантовать только conv1 блока кодировщика 0.
2. Объем масштабного коэффициента (на канал, а не на тензор)
Коэффициент масштабирования используется для сопоставления fp32 с int8. Пертензор означает, что мы используем один масштабный коэффициент для одного слоя (всех каналов). Поканальное квантование означает, что у нас есть разные масштабные коэффициенты для каждого канала. Это позволяет с меньшей ошибкой преобразовывать тензоры fp32 в квантованные значения. Это более выгодно, когда распределение веса сильно различается между каналами.
Примечание. PyTorch поддерживает поканальное квантование только для конвективных и линейных слоев. Изначально в TF был только тензор, но теперь они обеспечивают поканальное (по оси) квантование для Conv2d и DepthwiseConv2d.
3. Используйте симметричное квантование вместо асимметричного
Симметричное квантование (масштабное квантование) намного быстрее, чем асимметричное квантование (масштабное квантование + сдвиг). На изображении ниже (вам не нужно понимать уравнения) просто видите, что масштаб + сдвиг требует дополнительных операций:
Квантование с масштабированием + сдвиг может немного точнее представить тензоры fp32 в формате int8. Но все же полученная точность ничтожна.
Примечание: в PyTorch вам нужно просто установить
qscheme
наблюдателя. Поддерживаются 4 схемы -
4. Укажите серверную часть.
Операции умножения и сложения реализуются по-разному на оборудовании ARM и x86. Таким образом, указание оборудования во время процесса квантования поможет оптимизировать скорость вывода. ARM обычно используется в небольших энергоэффективных устройствах, таких как телефоны (Android, iOS) и Raspberry Pi, а x86 используется на компьютерах и серверах.
Примечание. В PyTorch вы должны использовать
fbgemm
иqnnpack
для X86 и ARM соответственно. Например - дляqnnpack
вы должны выполнить два шага -
1. Добавьте эту строку после импорта torch -
torch.backends.quantized.engine = qnnpack
.
2. Укажите qconfig как:
torch.quantization.get_default_qconfig(‘qnnpack’)
.
Спасибо за чтение, и я надеюсь, что эти советы помогут вам в построении эффективных квантованных моделей. Если у вас все еще возникают проблемы с квантованием, напишите мне на [email protected].
Ниже я привел несколько полезных ссылок.
Использованная литература:
- Документы PyTorch: https://pytorch.org/docs/stable/quantization.html
- Документы TensorFlow: https://www.tensorflow.org/lite/performance/quantization_spec
- Блог квантования: https://heartbeat.fritz.ai/quantization-arithmetic-421e66afd842
- Nvidia GTC: https://developer.download.nvidia.com/video/gputechconf/gtc/2019/presentation/s9659-inference-at-reduced-precision-on-gpus.pdf
Примечание редактора: Heartbeat - это онлайн-публикация и сообщество, созданное авторами и посвященное предоставлению первоклассных образовательных ресурсов для специалистов по науке о данных, машинному обучению и глубокому обучению. Мы стремимся поддерживать и вдохновлять разработчиков и инженеров из всех слоев общества.
Независимо от редакции, Heartbeat спонсируется и публикуется Comet, платформой MLOps, которая позволяет специалистам по обработке данных и группам машинного обучения отслеживать, сравнивать, объяснять и оптимизировать свои эксперименты. Мы платим участникам и не продаем рекламу.
Если вы хотите внести свой вклад, отправляйтесь на наш призыв к участникам. Вы также можете подписаться на наши еженедельные информационные бюллетени (Deep Learning Weekly и Comet Newsletter), присоединиться к нам в » «Slack и подписаться на Comet в Twitter и LinkedIn для получения ресурсов, событий и гораздо больше, что поможет вам быстрее и лучше строить модели машинного обучения.