Обучение больших нейронных сетей на ПЛИС: утопия или…
Данная статья ставит себе целью проанализировать причины фактического неиспользования ПЛИС в задачах исследования и обучения нейронных сетей а также предложить концепцию их возможного эффективного применения.
Об авторе: опытный FPGA-разработчик, в последние несколько лет не принимавший участия в промышленной разработке. Наблюдения и выводы основаны на любительском опыте обучения сетей, обзорных статьях и новостях.
Причин исчезающе малого применения FPGA в области обучения нейронных сетей (НС) достаточно. Начиная со стандартных: сложность входа в разработку; громоздкие, медленные и довольно низкокачественные IDE; общее низкое число специалистов и, соответственно, слабое сообщество. И заканчивая специфической — бесконечная сложность написания кода по сравнению с PyTorch.
А во главе всего — отсутствие решающего преимущества, способного перевесить указанные минусы! Зачем, если CUDA+PyTorch лишены этих недостатков, а максимум, который может предложить ПЛИС, это повторить текущие решения?
В такой ситуации стоило бы ждать решительных шагов прежде всего от вендоров.. но этого нет. То награждают на конкурсе реализацию YOLOv5 — "сделали, а что дальше вы намерены делать?"(с), то уходят в новой архитектуре от квази бесшовной, однородной структуры к модульной. Ещё больше всё усложняющей но предоставляющей аж 400(!) ИИ-ядер.
По-настоящему изменить положение вещей могло бы предельное, на порядок и более, ускорение обучения больших НС с использованием ПЛИС. Подобное ускорение можно обеспечить путём параллельных вычислений сразу на многих «кристаллах», используя для передачи информации мощнейший интерконнект в виде высокоскоростных приемопередатчиков (трансиверов) — вещь, о которой почему-то несправедливо забыли.
В связи с этим была сформулирована следующая задача: реализовать систему конвейерной обработки информации на нескольких FPGA при обучении НС.
Далее речь пойдёт о том, что может сделать в контексте поставленной задачи 1 инженер, 1 средняя фирма и, самое главное, мог бы сделать вендор.
1 инженер
Возможности весьма ограничены. Возможно реализовать несколько стандартных слоёв, функций ошибки, протокол взаимодействия с клиентским PC, разместить всё в 1 «кристалле», обучить модель и по результатам оценить перспективы. Что и было сделано.
Для большей предметности была написана стандартная свёрточная нейросеть, тестируемая на Кинтекс 7, основная рабочая частота 300 МГц. Микросхема старая но сбалансированная, обеспечивающая двунаправленные 100 Гбит/c как с внешней памятью, так и с «предыдущей» и «последующей» микросхемами.
Данные для обучения загружаются по Ethernet 10G и в обработку поступают по 1 пикселю за такт. Математика целочисленная, 18 бит для весов и 22 для данных между слоями(всё настраиваемое). Веса хранятся в блочной/распределённой памяти. Входной поток подаётся в блок прямого распространения и параллельно записывается в FIFO (DDR3/BRAM) для вычислений при обратном распространении. После пулинга и функции активации поток, если возможно, уплотняется и передаётся в следующий слой простым FIFO — его интерфейс легко переносится на высокоскоростные приемопередатчики, но в текущей реализации они не используются за неимением аппаратного обеспечения.
При обратном распространении происходит синхронизация с вычислениями прямого прохода для совместного использования весовых коэффициентов. После подачи всех данных одного «батча» прямой поток останавливается до завершения обратного распространения и обновления весов(необходимость остановки под вопросом).
По этой причине, а также из-за необходимости обновления динамической памяти, коэффициент заполнения входного потока менее 100%, однако практическое снижение производительности незначительно и не превышает нескольких процентов. Структура вычислительного конвейера формируются из структуры данных в потоках на конкретном слое нейросети для максимального переиспользования ресурсов. SystemVerilog код нейронной сети, модулей взаимодействия с Ethernet, клиентская часть управления на python и эталонная модель на чистом numpy в репозитории. Так как для написания и отладки логики нейросети используется собственный вариант «HLS», то .sv код является «машинописным», однако его воспринимаемость удовлетворительна.
Результат
В результате была подтверждена возможность полностью параллельного высокоскоростного обучения простой нейронной сети и перспективность дальнейшего усложнения до ViT и GPT. Вместе с тем необходимо отметить 2 основных недостатка предложенной архитектуры:
Для Кинтекс 7, как поток в 100 Гбит/с для связи между слоями и с внешней памятью, так и 2000 DSP-блоков не выглядят чем-то значительным даже в рамках 1 слоя по-настоящему большой НС.
Однако в процессе тестирования были обнаружены множество путей для оптимизации. Например, для передачи между слоями не обязательно передавать integer, а достаточно передать «log2(int)» т.е. номер старшего бита и знак. Что сразу сжимает поток в несколько раз и одновременно снимает необходимость в аппаратных умножителях.
Доступно как кратное увеличение скорости расчёта путём подачи 2/4/8 и более пикселей на вход алгоритма за 1 такт при наличии ресурсов, так и прореживание входных данных для пропорционального уменьшения потоков между слоями — вариантов реализации с учётом гибкой природы ПЛИС действительно много.
Хранение весовых коэффициентов в разработанном алгоритме осуществляется во внутренней памяти, что очевидно не позволит обучать по-настоящему большие НС(10-100 млрд) на относительно старых семействах.
Современные же FPGA с одной стороны могут быть в 10 и более раз производительнее К7, а с другой в них наблюдается явный перекос в сторону скорости приёмопередатчиков относительно обмена с внешней памятью. Как следствие, логично рассматривать «горизонтальное» масштабирование — размещение 1 слоя нейросети параллельно в нескольких микросхемах.
1 средняя фирма
Собрать легко масштабируемую систему из нескольких плат, реализовать протокол синхронизации и управления для неё. Для применения создать простую в использовании автоматическую систему одновременной компиляции и перепрограммирования большого количества FPGA по оптическим каналам. Стандартизировать интерфейсы вновь создаваемых модулей и обеспечить их качественное тестирование. Разделить этап прототипирования на видеокартах и реальное обучение на ПЛИС.
Теоретически, в масштабах 1 организации с учётом уже существующего отдела FPGA-разработки, возможно при умеренных вложениях реализовать подобную систему. На порядок снизить время обучения новых моделей тем самым уменьшить время разработки новых решений и одновременно поднять экспертизу собственных инженеров. Но без участия вендоров проблему медленной разработки новых модулей решить сложно.
Альтера, Ксайлинкс и другие
Необходимостью является полностью готовая система высокоскоростного обучения нейронных сетей.
С аппаратной стороны выпустить плату с необходимым «обвесом» и стандартизировать интерфейсы к ним, подготовить проект для тестирования, написать клиентскую часть осуществляющую полное тестирование аппаратной части и выводящую информацию об его состоянии в удобной, наглядной форме. Отчёт о тестировании должен быть достаточно информативным для базового ремонта по рекомендациям производителя или гарантийной замены.
Разработчики нейронных сетей не должны заниматься «железом». Вообще!
Для взаимодействия с собранной вычислительной системой необходим базовый FPGA-проект с центральной частью в виде blackbox для пользовательской логики, в который входят стандартные интерфейсы потоков данных, а вне которого находится логика авто построения сети, синхронизация и доступ к flash-памяти загрузки каждой ПЛИС. На клиентской части реализовать GUI, в который отображается аппаратная составляющая и посредством которого осуществляется наглядный контроль соответствия ресурсов и интерфейсов вычислительной системы и описываемой НС.
Непосредственно для для разработки НС нужен верифицированный репозиторий модулей заполняемый в том числе пользователями, стандартизованные требования к новым модулям, а также мощный testbench для их верификации.
Итоговый маршрут проектирования:
Актуальным также являлся бы подход быстрой проверки какой-либо идеи полностью в облаке, если для этого достаточно использования стандартных модулей и публичных наборов данных.
В завершение немного лирики
Если обучать нейросеть на рассмотренной системе из нескольких FPGA на частоте ядра 300 МГц изображениями 640х640 и подавать на вход алгоритма 4 пикселя за такт, то для прогона 1 млн изображений необходимо около 6 минут. Я не могу судить в абсолютных значения долго ли это, но создаётся впечатление, что не долго. Мой инженерный опыт подсказывает, что тест длительностью одного порядка со временем компиляции(30-90мин) не является слишком обременительным.
Когда читаю статьи в духе "мы обучали нашу сеть 4 дня, наконец поняли, что в ней ошибка — и начали заново" или "ребята из университета Y провели исследование и выяснили, что эффект YY связан с некорректным применением метрик", то испытываю определённое замешательство. С одной стороны - опытные энергичные специалисты, разработчики околопередовых решений, а с другой - иногда совсем «детские» ошибки в базовых вещах, не исправляемые месяцами и годами.
И ведь только непомерно высокая длительность эксперимента определяет, на мой взгляд, наличие подобных ошибок и иногда низкий уровень практического знания в области обучения больших НС. Области, где теория пишется фактически постфактум лишь объясняя полученные результаты.