В этом руководстве показано, как повысить эффективность вывода ресурсов модели с помощью квантования с помощью PyTorch Lightning - вторая часть серии знакомит с основами оптимизации моделей с помощью квантования.

PyTorch Lightning позволяет быстро обучать модели, не беспокоясь о шаблонах. Хотя это упрощает обучение, на практике модели обучаются не ради моделей обучения, а, скорее, для развертывания в производственных приложениях.



Почему мне следует использовать PyTorch Lightning?
devblog.pytorchlightning.ai



Это вторая часть нашей серии статей о том, как повысить эффективность вывода (вычисления, память, время) с помощью квантования модели.

В вводном посте серии мы обсудили выбор модели и обучили базовую модель с плавающей запятой для распознавания речевых команд.

  1. Обучение базовой модели

2. Оптимизация модели с помощью квантования

  • Что такое квантование?
  • Как выглядят квантованные тензоры?
  • Почему возможно квантование и как оно улучшает скорость?
  • Различные способы квантования
  • Почему такое сложное квантование?
  • Как мы собираемся преодолевать сложности

3. Квантование модели с помощью PyTorch Lightning

4. Анализ, выводы и дальнейшие шаги

Итак, без лишних слов, давайте погрузимся!

Оптимизация модели с помощью квантования

Теперь, если вы похожи на меня, вы, вероятно, думаете: окей, квантование, насколько это может быть сложно? Разве это не просто флаг PyTorch Lightning Trainer?

Но, как всегда в глубоком обучении, детали сложнее, чем кажется на первый взгляд, поэтому нам нужно время, чтобы немного больше понять о квантовании, прежде чем применять его к нашей модели.

В этом посте мы стремимся ответить на следующие вопросы:

  • Что такое квантование?
  • Как выглядят квантованные тензоры?
  • Почему возможно квантование и как оно улучшает скорость?
  • Различные способы квантования
  • Почему такое сложное квантование?
  • Как мы собираемся ориентироваться в сложности

Что такое квантование?

Квантование - это метод, при котором параметры модели и вычисления выполняются с целыми числами вместо чисел с плавающей запятой. Хотя 32-битные числа с плавающей запятой более или менее стандартны для обучения и сохранения нейронных сетей, мы стремимся использовать вместо них 8-битные целые числа.

Как выглядят квантованные тензоры?

Когда у нас есть числа с плавающей запятой, но мы собираемся вычислять с 8-битными целыми числами, мы должны думать о том, как представлять значения в 8-битных целых числах.

Типичным представлением будет линейное аффинное квантование: вместо значения с плавающей запятой x мы сохраняем x / scale + zero_point как целое число.

Мы можем попробовать это вручную, используя torch.quantize_per_tensor.

Дает результат вроде (первые несколько значений случайны)

Видим округление. Обратите внимание, как 3.0 в последней записи ограничен, потому что параметры квантования делают 2.54 наибольшим представимым значением.

Метод dequantize возвращает нас обратно к плавающей запятой.

Почему возможно квантование и как оно улучшает скорость?

Во-первых, давайте посмотрим, как квантование помогает нам повысить эффективность:

  • Часто вычисления с плавающей запятой медленнее (например, при большем количестве циклов на операцию) или у нас есть специализированное оборудование для целочисленных операций (как на последних графических процессорах). Это, пожалуй, наиболее интуитивно понятный, но наименее важный вклад в повышение эффективности.
  • Многие общие операции нейронной сети ограничены пропускной способностью памяти (и размерами кеша), поэтому работа с 8-битными записями вместо 32-битных позволяет нам читать и записывать данные из и в память в 4 раза быстрее.
  • Хранение тензоров веса с 8 битами на запись экономит нам 3/4 ОЗУ и места на жестком диске, необходимого для контрольных точек модели. Это хорошо, потому что наша среда развертывания обычно более ограничена памятью, чем наша тренировочная установка.

Теперь, когда мы знаем, почему 8-битные вычисления могут быть намного быстрее, чем 32-битные, почему мы вообще можем ожидать, что это сработает?

Наша модель из предыдущего поста представляет нейронные сети в том смысле, что ключевые операции - это умножение матриц и свертки. В обоих случаях каждый выход представляет собой сумму произведений входов с весами. Если мы интерпретируем это как форму среднего и предполагаем, что ошибки округления независимы и одинаково распределены с нулевым средним, центральная предельная теорема говорит нам, что ошибка аппроксимации в результате имеет хорошее поведение. Что ж, здесь мы делаем много предположений, и нам нужно немного формализовать это.

Чтобы интуитивно обосновать усреднение: одна вещь, на которую люди тратят много усилий, - это то, чтобы активации не взрывались при переходе от одного уровня к другому - от схем инициализации до уровней нормализации и до нормализации веса и стандартизации. Но если активации не взрываются (или не исчезают) в наших линейных слоях, мы фактически берем средние значения с весами, которые могут быть или не совпадать с тем, о чем вы обычно думаете, когда слышите «средневзвешенное значение».

Еще кое-что об этой интуиции: она также говорит нам, почему мы обычно хотим, чтобы 0 был точно представлен в нашей схеме квантования. При использовании активации ReLU многие значения сопоставляются с 0. Если 0 не является точным представлением, наши ошибки округления не имеют шансов быть нулевыми средними.

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

Различные способы предварительного квантования

Поэтому, если мы хотим, чтобы наша нейронная сеть имела квантованные параметры, нам нужны значения для них, но также необходимо придумать шкалы и нулевые точки как для параметров, так и для активаций.

Есть три основных способа квантования:

  1. Статическое квантование после обучения: здесь мы берем легко обученную модель - так что у нас есть значения параметров - и запускаем ее несколько раз с входными данными, наблюдая за значениями, чтобы найти подходящие масштабы и нулевые точки. Это, пожалуй, самый распространенный вариант квантования.
  2. Динамическое квантование: даже если у нас нет хорошей обработки размеров активации - например, в RNN - мы все равно можем извлечь выгоду из ускорения и сжатия квантования: мы можем квантовать веса (уменьшая размер модели), а затем, при запуске модели, квантовать входные данные, вычислить выходные данные с целыми числами и деквантовать их. Поскольку для вычисления сверточных и линейных слоев обычно требуется гораздо больше элементарных операций, чем для (деквантования), ускорение в первом случае обычно перевешивает дополнительные усилия, необходимые для второго.
  3. Обучение с учетом квантования: (обычно приводящее к статически квантованной сети). Здесь мы намеренно вводим квантованное округление «как если бы» в прямом направлении, но сохраняем веса как числа с плавающей запятой, а в обратном направлении без изменений. Это позволяет градиентам постепенно перемещать веса с плавающей запятой, даже если для фактического изменения округленного (то есть квантованного) веса требуется несколько шагов. После тренировки делаем правильное квантование. Поскольку мы ожидаем эффекта округления при оптимизации, мы можем ожидать, что потери будут ниже, чем при посттренировочном квантовании.

Практическое правило Томаса. Какой метод работает, примерно показано на следующей блок-схеме:

В нашем случае мы выбрали обучение с учетом квантования.

Почему сложно квантовать?

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

Применение квантования на практике может быть сложным по нескольким ключевым причинам:

  • Квантование - это «односторонняя» операция, которая необратимо меняет структуру нашей сети. Это также приводит к некоторым грубым краям, например. с сохранением и загрузкой чекпоинтов. Текущий инструментарий не предусматривает возврата квантованного модуля к числам с плавающей запятой. (На мой взгляд, это может быть очень желательной функцией, чтобы иметь возможность лучше повторять / настраивать квантованную модель.)
  • В отличие от процессоров / графических процессоров, которые используются с самого начала PyTorch и где операторы обычно должны работать с любым типом устройств, серверные модули квантования имеют ограниченный охват оператора. Эта поддержка со временем будет увеличиваться, но может показаться, что полное квантование не является целью разработки PyTorch, и операции не будут волшебным образом поддерживаться, если кто-то их не реализует или не отстаивает их реализацию с людьми, которые могут с этим справиться.
  • Как мы увидим в следующем разделе, нам нужно иметь дело - по крайней мере, с текущим инструментарием - с рядом вещей, находящихся на низком уровне, которые PyTorch и Lightning обычно абстрагируют для нас.

Как ориентироваться в сложности квантования.

В следующем разделе мы вернемся к нашей модели распознавания речевых команд и проведем квантование.

Теперь, в идеальном мире, мы бы исправили недостатки инструментария, на который я намекал выше, а затем опубликуем это руководство в версии, в которой вся скука исключена из процесса. Но пока мы должны представить себе карту, которая проведет вас по некоторым скалам.

Я постараюсь найти баланс, чтобы дать вам реалистичную картину того, чего вы можете ожидать при квантовании собственной модели, и при этом не утомлять вас слишком большим количеством трассировок стека.

В целом, это руководство предоставит явный набор инструкций и примеров того, что вам нужно знать при квантовании ваших собственных моделей для развертывания.

Следующие шаги

Уф! Это было много теории и не так много кода. В следующий раз берем код из первой части и применяем квантование. Тогда у меня тоже будет записная книжка, чтобы ты снова запустил ее, обещаю!

На этом мы завершаем вторую часть нашего урока. Следите за обновлениями следующих двух

  • Квантование модели с помощью PyTorch Lightning
  • Анализ, выводы и следующие шаги

Благодарности

Это сообщение в блоге спонсируется Grid.ai. То, что вы могли прочитать это сообщение в блоге до тех пор, пока оно здесь не было, полностью связано с фантастическим редактированием Ари Борнштейна.

об авторе

Томас Виманн - автор книги Deep Learning with PyTorch от Manning Publications. Имея более 150 функций и исправлений ошибок, он является одним из самых плодовитых независимых разработчиков PyTorch. Через свою компанию MathInf GmbH с 2018 года он предоставляет качественные консультации и тренинги по машинному обучению и PyTorch. Он имеет докторскую степень. по карандашной математике и блогам на Lernapparat.de.