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

Автор: Dr. Марио Майкл Крелл, Чжэньинг Лю, Эммануэль Менаж и Бартош Богдански

Инженеры Graphcore продемонстрировали выдающуюся производительность в соответствии с последними результатами обучения MLPerf v1.1, опубликованными в декабре 2021 года [9], при этом наш IPU-POD16 превзошел флагман Nvidia DGX A100 на ResNet-50.

Здесь мы объясним, как наша команда добилась таких ускорений в масштабе этой популярной модели компьютерного зрения. В этом техническом руководстве мы раскроем различные методы и стратегии, используемые инженерами Graphcore, включая эффективное масштабирование оборудования, оптимизацию памяти, отслеживание экспериментов, оптимизацию производительности и многое другое. Сосредоточив внимание на оптимизации тестов для ResNet-50 в MLPerf для IPU [9], это руководство дает общее представление о мыслительном процессе оптимизации тестов, которые также могут быть применены к другим приложениям и оборудованию.

Ускорение ResNet-50

Для наших результатов MLPerf v1.1, опубликованных в декабре 2021 года [9], мы достигли времени обучения 28,3 минуты для обучения ResNet-50 на ImageNet (RN50) с пропускной способностью 30 000 изображений в секунду и 38 эпохами до сходимости при проверке 75,9%. точность на IPU-POD16. До того, как мы начали наш первый проект MLPerf в 2020 году, пропускная способность для обучения ResNet-50 составляла около 16 000 изображений в секунду, и для достижения сходимости потребовалось примерно 65 эпох. Если объединить эти цифры, мы получим общее улучшение в 3,2 раза. Затем мы масштабировали приложение с IPU-POD16 на наш IPU-POD256, что дало нам еще 7,5-кратное увеличение времени обучения и 12-кратное увеличение пропускной способности. Так как же мы добились такого ускорения?

Инструменты, которые мы разработали в процессе, представлены в наших общедоступных примерах и не являются специфическими для RN50 или теста MLPerf. Мы подумали, что другие разработчики IPU могут найти их полезными для своих моделей. Ключевые ингредиенты:

  • Оптимизированное распределение заданий и общение
  • Оптимизированный ввод-вывод хоста и расположение данных с распределением по нескольким хостам
  • Отслеживание экспериментов по весам и смещениям
  • Небольшие эффективные размеры партий
  • Переход с SGD с Momentum на оптимизатор LARS
  • Распределенный батч-норм с кешированием статистики
  • Контрольные точки пересчета вместо конвейерной обработки
  • Стохастическое округление
  • Оптимизированные профили компиляции и памяти

IPU-POD: создан для ускорения ИИ до уровня суперкомпьютеров

Как оборудование IPU масштабирует приложения машинного обучения

Чтобы масштабировать наше приложение, необходимо было реализовать множество функций. Серьезной проблемой при масштабировании является увеличение размера пакета и связи, что требует времени для передачи данных и памяти для кода. Для локальных реплик мы хотим, чтобы размер микропакета был как можно больше, чтобы получить хорошие статистические оценки для нормы пакета, которая является ключевой частью модели ResNet-50. Градиенты для каждой реплики необходимо агрегировать, и оптимизатор выполняет их обновление.

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

В наших экспериментах лучшим компромиссом для IPU-POD128 и IPU-POD256 было использование счетчика накопления градиента, равного 2, чтобы иметь немного уменьшенную связь, но чтобы эффективный размер пакета был как можно меньше. Учитывая больший размер пакета, изменения, упомянутые в «Оптимизаторе LARS и оптимизации гиперпараметров», были необходимы, поскольку SGD увеличил бы требуемые эпохи намного больше, чем LARS. Кроме того, мы чрезмерно использовали наш инструмент распределения нагрузки PopDist, как описано в разделе «Масштабирование связи между хостом и IPU». Увеличивая количество хостов с локальным хранилищем данных, мы улучшаем пропускную способность загрузки данных и следим за тем, чтобы не было замедления передачи данных, сколько бы акселераторов не использовалось.

Аппаратное масштабирование: подключение платформ IPU-POD64

IPU-POD от Graphcore были разработаны с нуля с учетом этой масштабируемости, о чем свидетельствует невероятное масштабирование, продемонстрированное в нашем последнем представлении MLPerf. Внутри стойки IPU напрямую соединяются друг с другом, образуя два кольца с помощью высокоскоростного соединения IPU-Link. Используя эти прямые соединения, каждый IPU-POD64 обеспечивает огромную пропускную способность IPU-Link 10,24 ТБ/с со сверхнизкой задержкой (250 нс). Помимо этих вертикальных соединений внутри стойки, IPU подключаются к стойкам (напрямую или через коммутатор), образуя горизонтальное кольцо. Это означает, что удвоение количества стоек более чем вдвое увеличивает доступную полосу пропускания.

Коммуникационная библиотека Graphcore (GCL) была разработана для полного использования этих аппаратных функций.

IPU-POD128 и IPU-POD256 состоят из нескольких модулей IPU-POD64. Один IPU-POD64 состоит из 16 IPU-M2000, установленных вертикально и соединенных с помощью IPU-Link, чтобы сформировать 2D-Torus. Гибкость нашего масштабируемого решения позволяет нам соединять IPU-POD64 вместе горизонтально для формирования более крупных систем. Существует два возможных метода подключения таких систем: напрямую (каналы GW на одном IPU-M подключаются напрямую к модулям IPU-M2000 на других системах IPU-POD64) или через коммутируемую матрицу, где каналы GW на всех модулях IPU-M2000 подключаются к коммутаторам. которые затем пересылают трафик на правильные IPU-M2000 назначения на другие IPU-POD64. В обоих случаях синхронизация между несколькими IPU-POD64 отправляется по каналам GW-Link без необходимости использования физических линий синхронизации для обеспечения более простого масштабирования. Для IPU-POD128 и IPU-POD256, которые мы используем для работы MLPerf, мы используем коммутируемое решение, поскольку оно позволяет нам быть более гибкими и обеспечивает лучшую отказоустойчивость.

Глядя на отдельные аспекты топологии горизонтального масштабирования IPU-POD, теперь мы можем сделать снимок того, как это выглядит на практике. Это показывает, что даже при всей гибкости и великолепных возможностях, которые дает развертывание поверх существующей коммутируемой фабрики, на самом деле это не так интенсивно, как может показаться на первый взгляд с точки зрения необходимого «дополнительного комплекта». Эта система имеет 8 стоек IPU-POD64, поэтому мы можем назвать ее IPU-POD512. Соединить все каналы GW между каждым IPU-M2000 в IPU-POD512 можно с помощью всего двух коммутаторов 128 портов — 100GbE.

Масштабирование связи с помощью коммуникационной библиотеки Graphcore (GCL)

Чтобы ускорить обучение моделей ИИ, одна из идей состоит в том, чтобы воспроизвести модель на многих IPU, каждый из которых будет обрабатывать разные пакеты. После обработки пакета реплики делятся тем, что они узнали из пакета (градиенты), используя сокращение all. В идеальном случае, если бы All-Reduce был мгновенным, у нас было бы идеальное масштабирование в смысле пропускной способности: удвоение количества реплик позволило бы обрабатывать вдвое больше обучающих выборок.

В GCL реализовано несколько оптимизаций, обеспечивающих масштабирование за пределы одного IPU-POD64. Весь обмен внутренними данными реплики модели известен и детализируется Poplar во время компиляции, и с предположением, что все коллективные коммуникации, детали модели машинного обучения и топология сети также известны во время компиляции, выполнение GCL является детерминированным и может быть запланировано и оптимизировано соответствующим образом. . GCL также предоставляет общедоступный API для указания коммуникационных групп как подмножеств общего набора реплик, что дает нам гибкость для выполнения операций в больших системах. Для большего масштабирования до IPU-POD256 мы используем поэтапное все сокращение, где тензорное сокращение в системе с несколькими POD выполняется как три отдельные операции.

Во-первых, ReduceScatter выполняется по каналам IPU-Link внутри каждого из IPU-POD64, которые являются строительными блоками IPU-POD256. Выходные данные Reduce Scatter становятся входными данными для All-Reduce, работающего по каналам GW. Это обеспечивает обмен элементами данных между несколькими IPU-POD, гарантируя, что каждая реплика на одном уровне содержит одни и те же данные. Наконец, коллективная операция All-Gather выполняется на выходе All-Reduce и снова выполняется внутри каждого отдельного IPU-POD64, так что каждая реплика в конце содержит одну и ту же копию данных.

Важнейшей характеристикой нашей реализации является то, что время, затраченное на All-Reduce, является функцией общего объема данных, которые нужно разделить, на общую доступную пропускную способность. Поскольку удвоение числа IPU означает удвоение пропускной способности, время All-Reduce остается постоянным. Постоянное время All-Reduce — ключевая особенность предложения Graphcore: оно позволяет новаторам экспериментировать быстрее за счет использования большего количества оборудования, эффективно сокращая цикл обратной связи, что в конечном итоге приводит к захватывающим открытиям.

Учитывая небольшое количество накопленных градиентов, равное 2 для больших систем, любая оптимизация передачи градиентов оказала большое влияние на нашу производительность масштабирования. Например, мы сгруппировали тензоры разных типов и форм вместе и сделали коммуникацию одним кадром. Кроме того, чтобы в полной мере использовать пропускную способность, мы оптимизировали шлюз между хостом и IPU для немедленной пересылки данных и, таким образом, значительного сокращения задержки в различных приложениях. Каждый IPU-POD64 имеет собственный шлюз. Таким образом, это изменение в основном приносит пользу масштабированию с IPU-POD16 на IPU-POD64.

Оптимизация памяти для масштабирования

В то время как память, необходимая для данных, остается неизменной при масштабировании, для кода обмена требуется дополнительная память. Таким образом, оптимизация памяти, упомянутая, например, в разделе «Другая оптимизация памяти и скорости», имела решающее значение для нашего успеха в масштабировании, тем более что оптимизатору LARS требовалось даже больше памяти, чем SGD. Конкретной оптимизацией для масштабирования до IPU-POD128 и IPU-POD256 стало уменьшение размера кода для обмена между IPU-POD.

Масштабирование проверки на IPU-POD256

Для проверки не требуется обратный проход, а в слоях норм партии применяются синхронизированное скользящее среднее и дисперсия. Таким образом, вычислительная схема существенно отличается. Чтобы не тратить время на замену графов, мы вместо этого применяем схему оценки в автономном режиме, т. Е. Мы сохраняем контрольные точки во время обучения, а затем оцениваем производительность, используя данные проверки. Мы также сохраняем ту же конфигурацию IPU, чтобы избежать времени на перенастройку. Это означает, что в случае POD256 у нас есть 128 хост-процессов, каждый из которых отвечает за один файл проверки, а результаты затем объединяются для расчета общей производительности. Поскольку мы работаем со статическими графами, 50000 проверочных изображений не могут быть идеально разделены даже при размере пакета 1, что было бы неэффективно. Однако для настройки MLPerf необходимо обработать все изображения, а образцы нельзя пропускать. Таким образом, мы дополняем наши данные до следующего большего пакета, а затем удаляем результаты заполнения в постобработке.

Ускорение ResNet-50 в масштабе на оборудовании IPU

Отслеживание экспериментов

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

Уменьшение количества эпох

Пакетная норма против групповой нормы

На практике люди обычно обучают свою сеть около 90 эпох или даже больше. Поскольку бенчмарк MLPerf заботится только о времени обучения, для уменьшения этого числа проводится множество настроек. Нашей целью было сократить количество эпох до 44 или даже меньше, учитывая предыдущие результаты в соревновании. Наша исходная реализация использовала групповую норму вместо пакетной нормы для более быстрой обработки и избегания зависимости между выборками. Обсуждение см. в [1].

Для 65 эпох и более эта нормализация работает отлично. Однако при точной настройке гиперпараметров мы узнали, что требуется более агрессивная и дорогостоящая нормализация, чтобы получить сходимость в желаемом небольшом количестве эпох. Это означает, что инструменты, которые мы разработали для обеспечения больших пакетных норм, были специфичны для эталонного теста MLPerf в том смысле, что они должны были уменьшить количество эпох. Без этого требования мы могли бы придерживаться групповой нормы.

Увеличение размера партии

Наша первоначальная установка представляла собой конвейер из 4 IPU (Intelligence Processing Units) с коэффициентом репликации 4 для параллельной обработки данных и группового расписания. Мы использовали размер партии 16. Изменение этого параметра на норму партии было простым изменением конфигурации, но сходимость улучшилась лишь незначительно. Стало лучше, когда мы точно настроили этапы памяти и конвейера, чтобы получить размер пакета 24, используя эффективную связь с памятью, ограничив размер памяти кода для каждого IPU и отрегулировав длину этапов конвейера. Тем не менее, мы не смогли достичь ожидаемых 44 эпох. Итак, мы провели несколько симуляций и обнаружили, что размера пакета 32 должно быть достаточно. При моделировании мы могли достичь сходимости за 44 эпохи, но пропускная способность была ниже приемлемой, и нам потребовались некоторые настройки, как описано в разделе «Увеличение пропускной способности».

Небольшой эффективный размер партии

Для получения хорошего аппаратного ускорения обычно приходится работать с большими пакетами данных. Использование большего количества данных на одном ускорителе обычно увеличивает использование АЛУ (арифметико-логического устройства) и обеспечивает достаточную нагрузку на ускоритель. Обратите внимание, что IPU имеет уникальный способ распределения рабочих нагрузок, а также может ускорять рабочие нагрузки с небольшими размерами пакетов. Кроме того, передача градиентов и обновлений оптимизатора может быть дорогостоящей, поэтому пропускную способность можно увеличить, сделав эти обновления менее частыми, например, используя накопление градиентов. Обратите внимание, что накопление градиента дает убывающую отдачу с каждым увеличением. В наших экспериментах мы поняли, что большие размеры пакетов требуют больше эпох для обучения, что также можно увидеть в эталонных точках сходимости MLPerf [8]. Таким образом, преимущество больших партий может перевесить выигрыш в скорости. С другой стороны, для каждой «реплики» требуется минимальный размер партии 32 экземпляра, чтобы норма партии работала.

Для оптимальной конфигурации IPU-POD16 мы получили эффективный размер пакета 3200 (16 реплик, каждый с размером микропакета 20 и счетчиком накопления градиента 10), которые сходились в 38 эпохах. Для масштабирования до более крупных систем мы соответственно уменьшили счетчик накопления градиента. Из-за эффективности связи и оптимизации на более крупных машинах было достаточно поддерживать счетчик накопления градиента равным 2. Для системы IPU-POD64 мы использовали аналогичный эффективный размер пакета 3840 (64 реплики, счетчик накопления градиента 3) для также сходятся в 38 эпохах. Для IPU-POD128 и IPU-POD256 мы использовали счет накопления градиента, равный 2, с эффективным размером пакета 5120 и 10240 и соответствующими эпохами до сходимости 41 и 45. Использование больших размеров увеличило бы количество эпох намного больше и не было достижимый.

LARS Optimizer и оптимизация гиперпараметров

В то время как обычные настройки машинного обучения демонстрируют некоторую надежность при выборе гиперпараметров, малое количество эпох в MLPerf делает сходимость чувствительной к любым изменениям. Лучше всего это видно по выбору оптимизатора. Известно, что LARS является хорошим оптимизатором для больших партий. Во время нашего проекта мы узнали, что он также является лучшим оптимизатором, чем стохастический градиентный спуск с импульсом (SGD), в том смысле, что для сходимости требуется меньше эпох. Это преимущество растет с увеличением размера партии. Обратите внимание, что для LARS требуется больше памяти и вычислительных ресурсов, но небольшие затраты превышают значительную экономию. Одним из основных изменений между нашей первой и второй отправкой MLPerf была оптимизация использования памяти и включение LARS, что привело к значительному ускорению. Например, для нашей установки IPU-POD16 LARS сократил количество необходимых эпох с 44 до 38. Одним из ключевых компонентов является количество эпох прогрева. В то время как SGD требует 5 эпох, LARS может работать только с 2 эпохами. Еще одним чувствительным гиперпараметром является параметр затухания веса в LARS, уменьшая его в два раза и регулируя скорость обучения, ускоряет сходимость до 2 эпох.

Увеличение пропускной способности

Балансировка трубопровода

В отличие от модели обработки естественного языка BERT, оптимизация конвейеров для RN50 может оказаться сложной задачей. Существует множество различных компонентов, для которых требуется разный код, и размер данных между слоями сильно меняется. Таким образом, небольшая модификация стратегии разделения может оказать серьезное влияние на профиль памяти, переходя от большого количества оставшейся памяти к требуемому слишком большому объему памяти. Кроме того, вычислительная нагрузка может быть сильно несбалансированной, как мы обнаружили с помощью анализатора графов PopVision. Четвертому IPU потребовалось вдвое больше времени для обработки по сравнению со вторым, и не было места для балансировки из-за требований к памяти для данных. С другой стороны, IPU0 не мог слишком много обрабатывать, потому что у него был самый большой запас активаций для хранения. Точно так же IPU1 и IPU2 также имели некоторое время простоя, которое даже больше, чем синхронизация, показанная зеленой полосой. Из-за несбалансированных требований к вычислениям и памяти дальнейшие улучшения затруднительны, и мы выбрали другой путь, используя подход пересчета, который может работать на одном IPU, и использует норму распределенного пакета, чтобы обеспечить достаточно большой размер пакета.

Распределенная норма партии

Наша реализация пакетной нормы объединена и оптимизирована на уровне Poplar. Со всей тонкой настройкой памяти, которую мы использовали ранее для настройки конвейера, мы поняли, что теперь можем увеличить размер пакета в новой настройке на одном IPU с 6 до 12 без какой-либо конвейерной обработки. Теперь, чтобы получить размер партии 32 для нормы партии, нам нужна только распределенная норма партии. Для всего остального будет достаточно обычной параллельной обработки данных. Мы добавили эту функцию в нашу структуру всего несколькими строками кода, где мы агрегировали статистику по нескольким репликам в рамках реализации нормализации. Этот подход был очень эффективным и не требовал много памяти, тем более, что векторы для статистики довольно малы. Кроме того, обратный проход был просто агрегацией градиентов между IPU, которые вносили свой вклад в норму распределенного пакета и, таким образом, приводили только к одной строке кода.

Для кода приложения в TensorFlow 1.15 интерфейс оставался минималистичным. Должен быть установлен только номер конфигурации:

Для размера пакета 12 нам потребуется агрегировать данные как минимум между 3 IPU, чтобы достичь стандартного размера пакета не менее 32. Чтобы избежать связи между машинами IPU-M2000, вместо этого должно быть 4 IPU.

Перерасчет

Для повышения пропускной способности и уменьшения коммуникационных издержек по сравнению с нормой распределенного пакета мы хотели увеличить размер пакета и ограничить норму распределенного пакета двумя IPU. Таким образом, мы воспользовались пересчетом. Поскольку в TensorFlow 1.15 нет встроенной поддержки для этого, мы использовали программный трюк. Конвейерная реализация IPU поставляется с последовательным расписанием, которое можно использовать для разделения вычислительного графа на несколько IPU. Вместо этого мы не распределяли обработку по нескольким IPU, а сохранили их все на одном IPU. Обратите внимание, что размер кода во встроенной памяти почти не увеличивается, но многие промежуточные активации не сохраняются, а пересчитываются. Таким образом, мы освобождаем много памяти, которую можно использовать для увеличения размера пакета. Установив наши разбиения на b1/0/relu, b1/2/relu, b2/0/relu, b2/2/relu, b3/0/relu, and b3/3/relu, мы увеличили размер пакета до 20. Мы могли бы использовать меньше точек пересчета, разгрузив часть состояния оптимизатора на хост. Мы воздержались от такой возможности и сохранили все в памяти, потому что мы лучше использовали полосу пропускания связи, передавая больше данных в IPU. Итак, все, что требуется для перерасчета, это три ингредиента:

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

Масштабирование связи между хостом и IPU

Для теста ResNet-50 загрузка данных при предварительной обработке является важной частью рабочей нагрузки. В одном из наших экспериментов мы попробовали хост на базе Intel с меньшим количеством ядер ЦП, что значительно замедлило нашу обработку по сравнению с использованием хоста AMD. Таким образом, наша дезагрегированная архитектура хоста особенно важна для возможности выбора правильного хоста для приложения.

Простой способ увеличить объем передаваемых данных — уменьшить их размер. Данные дополненного изображения передавались в формате Int8, после чего нормализация происходила на IPU, а не на хосте. Нормализация была реализована как объединенная операция, которая приводила данные к типу Float16 и добавляла четвертый канал с нулями, чтобы уменьшить объем памяти, занимаемый последующим сверточным слоем.

Кроме того, для передачи большего количества данных загрузку данных необходимо распараллелить с помощью среды Graphcore PopRun [6]. Наш анализ показал, что для каждого набора из двух реплик лучше всего подходит один хост-процесс. Каждый хост работал оптимально с 8 узлами, поддерживающими numa, по 4 на каждый ЦП. Таким образом, для IPU-POD 16, 64, 128 и 256 мы использовали 1, 4, 8 и 16 хостов соответственно. Команда выглядит примерно так:

poprun --host $HOSTS $MPI_SETTINGS --num-instances “$INSTANCES” --num-replicas “$REPLICAS” python train.py args

Осведомленность о нуме активируется с помощью --numa-aware 1” в $MPI_SETTINGS. В то время как хост-процессы являются независимыми процессами MPI, комбинированное представление вычислительного графа по всем репликам создается на нескольких стойках. Каждый хост-процесс читает отдельный набор входных файлов одинакового размера. Таким образом, исключается любой конфликт при чтении файла. Данные распределенного чтения хранятся в кеше, хотя влияние на производительность незначительно.

Другие оптимизации памяти и скорости

Помимо пересчета, мы использовали еще несколько стратегий оптимизации:

  • Мы храним статистику норм партии, чтобы избежать пересчета.
  • Мы сделали все расчеты в FP16 для весов, активаций и градиентов. Мы также использовали стохастическое округление для улучшения сходимости и получастные для сверток и умножения матриц для ускорения. Стохастическое округление поддерживается нашим оборудованием. Обратите внимание, что обновление веса должно иметь одно и то же обновление для каждой реплики, чтобы веса оставались согласованными. Это достигается за счет синхронизации начальных начальных значений с помощью широковещательной передачи хоровода
    with tf.Graph().as_default(), tf.Session():
    identical_seed = hvd.broadcast(
    identical_seed, root_rank=0, name=”broadcast_seed”).eval()

    и обеспечения одинакового начального заполнения IPU при применении обновления веса. Это достигается с помощью
    export POPLAR_ENGINE_OPTIONS=’{“target.deterministicWorkers”:”portable”}’
  • Мы точно настроили баланс между памятью, используемой для кода, и памятью, используемой для хранения активаций в IPU, оптимизировав “availableMemoryProportion” IPUConfig [5], что привело к значению около 0,15.
    config.convolutions.poplar_options[‘availableMemoryProportion’] = …

Чтобы узнать больше об оптимизации памяти и обработки, ознакомьтесь с нашим новым руководством [4].

Ограничения

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

  • Целевая точность, требуемая бенчмарком, ниже максимально достижимой.
  • Для эталонного теста требуется сходимость только 4 из 5 прогонов. Если есть один сбой, его увольняют.
  • Можно изменить только часть гиперпараметров, и единственными доступными оптимизаторами являются SGD с Momentum и LARS.
  • Целевая метрика — время на обучение/схождение, а не пропускная способность. Вероятно, это связано с тем, что при более высоких размерах пакетов и накоплении пропускная способность может быть увеличена, но время конвергенции займет гораздо больше эпох.
  • Мы оцениваем только каждые 4 эпохи. Более высокая частота оценки противоречит правилам.
  • Обучение происходит исключительно на ImageNet.
  • График скорости обучения представляет собой полиномиальный график со степенью два, а не ступенчатый или косинусный график скорости обучения.

На практике никто не будет обучать ResNet-50 на ImageNet с точностью проверки 75,9%. Легче загрузить предварительно обученную сеть с более высокой точностью.

На практике можно было бы тренироваться на другом наборе данных с более высокой точностью. Однако при обучении на другом наборе данных выбранные параметры для этого теста могут не передаваться. Кроме того, может потребоваться большее количество эпох и другой график скорости обучения. Однако с увеличением количества эпох может быть лучше использовать групповую норму (или прокси-норму), если обучение происходит с нуля, а не с предварительно обученной моделью.

Точность Top1 в 75,9% недостаточна для некоторых приложений, таких как поиск. Представьте, у вас есть поисковая система на 100 000 000 изображений, таких как набор данных YFCC100M, и вы пытаетесь найти определенный класс изображений, например, оригами, используя ResNet-50 с такой точностью. Отсутствие 24% всех релевантных изображений может быть для вас нормальным. Проблема будет заключаться в том, что, поскольку другие классы также будут неправильно классифицированы, вы получите гораздо больше изображений, которые не являются оригами, а неправильными классификациями других изображений. На самом деле таких ошибочных классификаций будет большинство [2]. Для достижения более высокой точности стоит рассмотреть более современные модели, такие как EfficientNet, в которых используются некоторые функции, упомянутые в этом блоге. Вам также может быть интересно прочитать “Как мы сделали EfficientNet более эффективным”[3].

Заключение

Объединив мощную структуру TensorFlow 1.15 с инструментами Weights and Biases, Poplar и PopVision вместе с мощным IPU MK2, нам удалось в полной мере использовать скорость обработки и память и добиться потрясающей производительности.

Спасибо

Большое спасибо Брайану Нгуену, Годфри да Коште (и его команде) и Мриналу Айеру, которые сделали все возможное, чтобы эта работа состоялась.

Мы также хотели бы поблагодарить Alex Cunha, Phil Brown, Stuart Cornell, Dominic Masters, Adam Sanders, Håkon Sandsmark, George Pawelczak, Simon Long, Luke Hudlass-Galley, Jorge Беллону Кастро, Джорджу Мэтью и многим другим за их ценный вклад.

Рекомендации

[1] А. Лабати, Устранение пакетной зависимости в CNN с помощью прокси-нормализации активаций, На пути к науке о данных, 2021 г.

[2] Д. Ма, Г. Фридланд, М. М. Крелл, OrigamiSet1.0: два новых набора данных для классификации оригами и оценки сложности, arxiv 2021

[3] Д. Мастерс, Как мы сделали EfficientNet более эффективной, На пути к науке о данных, 2021 г.

[4] Руководство по оптимизации памяти и производительности, Graphcore

[5] Оптимизация использования временной памяти для сверток и матмул на IPU, Graphcore

[6] PopDist и PopRun: Руководство пользователя, Graphcore

[7] Н. Димитриу и О. Аранджелович, Новый взгляд на нормализацию призраков, arXiv 2020

[8] Эталонные точки сходимости MLPerf, MLCommons

[9] Результаты обучения MLPerf v1.1. MLPerf ID: 1.1–2040, 1.1–2042, 1.1–2044, 1.1–2045, 1.1–2065. Название и логотип MLPerf являются товарными знаками. См. www.mlperf.org для получения дополнительной информации.