Используйте общую память для более быстрой коллективной коммуникации, чем NCCL

искусственный интеллект алгоритм задняя часть Архитектура

Автор: Цао Бин | Архитектор MegEngine

Введение

Начиная с поколения видеокарт 2080Ti, копирование P2P было отменено для всех гражданских игровых карт, что привело к значительному снижению скорости обучения. В этом случае для обучения нескольких карт на одной машине в MegEngine реализован более быстрый алгоритм коллективной связи, который имеет эффект ускорения от 3% до 10% для обучения нескольких различных сетей по сравнению с NCCL.

В версии MegEngine v1.5 вы можете вручную переключить сервер коллективной связи на shm (по умолчанию nccl), нужно изменить только один параметр. (Поскольку режим shm требует дополнительной загрузки ЦП и может повысить эффективность только на определенных картах, он не включен по умолчанию)

gm = GradManager()
gm.attach(model.parameters(), callbacks=[dist.make_allreduce_cb("sum", backend="shm")])
目前只实现了单机版本,多机暂不支持

задний план

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

Для параллельной синхронизации данных в настоящее время существует два широко используемых метода: Parameter Server и Gradient AllReduce.

  • Для решения Parameter Server требуется дополнительная машина в качестве сервера параметров для обновления параметров, а метод централизованной связи оказывает сильное давление на полосу пропускания, а объем связи увеличивается линейно при увеличении обучающей машины;

  • Схема AllReduce только синхронизирует параметры между машинами, участвующими в обучении, не требует дополнительных машин и обладает хорошей масштабируемостью.

В настоящее время MegEngine также использует схему AllReduce в качестве схемы параллельной синхронизации параметров данных. В решении AllReduce в настоящее время обычно используется NCCL, библиотека коллективной связи GPU, написанная самой Nvidia, и эффективность связи очень высока.

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

Это здесь? Конечно, нет, в случае обучения 2080Ti с 8 картами мы имеем повышение производительности на 3-10% по сравнению с NCCL в нескольких сетях. (Возьмите 2080Ti в качестве примера, потому что игровая карта не поддерживает связь P2P, связь относительно медленная, время связи велико, и преимущества могут быть получены за счет экономии времени связи)

Как это делается, разберем пошагово (следующие данные все экспортируются с помощью megaengine.utils.profiler, а соответствующие документы находятся вдокументация профилировщика).

Обычно мы делаем градиентную синхронизацию в обратной фазе одновременно.Давайте посмотрим на обратное время одной карты, которое составляет всего 164 мс:

图 1(单卡 ResNet50 训练

Давайте посмотрим на обратное время обучения с 8 картами, которое увеличилось до 203 мс, что на 39 мс больше, чем в случае с одной картой:

图 2(使用 NCCL 做 8卡 ResNet50 训练)

Действительно, время назад стало намного длиннее, но почему? Можем ли мы его устранить?

1) почему

Одним словом: NCCL AllReduce занимает вычислительные ресурсы cuda, поэтому вычисления становятся медленнее.

Конкретная причина состоит в том, что ядро ​​Cuda, соответствующее NCCL Allredu, нуждается в связи, так и расчета, которые занимают расчет ресурсов расчета, но большую часть времени находится в связи, что приводит к высокой скорости утилизации вычислительных ресурсов.

2) Можно ли его устранить

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

3) Пример реальных тестовых вычислений и коммуникационного параллелизма

Stream0 выполняет умножение матриц, stream1 выполняет копирование, и на скорость умножения матриц до и после это не влияет:

图3(计算通信并行,stream0 做矩阵乘法,stream1 做 d2d copy)

Реализовать идеи

Вот два метода реализации AllReduce.

1) Уменьшить разброс + Все собрать

图4(ReduceScatter算子图解)

图5( AllGather 算子图解)

Ring AllReduce использует режим ReduceScatter + AllGather: сначала первый раунд связи вычисляет частичную сумму на каждом узле, а затем второй раунд связи собирает частичную сумму для получения окончательного результата.

2) Уменьшить + Трансляция

图6( Reduce 算子图解)

图7 (Broadcast算子图解)

Метод Reduce + Broadcast похож на Parameter Server, который сначала вычисляет полную совокупную сумму на одном узле, а затем передает ее на каждый узел.

В новом алгоритме используется метод Reduce + Broadcast: сначала все данные копируются на процессор (используя Shared Memory), затем процессор накапливает их, а затем копирует обратно на GPU.

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

图8(Shared Memory AllReduce 中 Reduce 阶段图解)

Поскольку используется общая память, этот бэкенд сокращенно называется SHM.

добиться эффекта

1) Производительность оператора

По сравнению с NCCL, SHM имеет немного большую задержку и меньшую пропускную способность и может достигать примерно 90% производительности NCCL, когда объем данных больше.

图9( SHM 和 NCCL 算子性能对比)

Производительность SHM необходимо задействовать в случае больших пакетов данных, и стратегия ParamPack может максимизировать эффект SHM (стратегия ParamPack используется в Distributed.make_allreduce_cb в MegEngine, а размер пакета по умолчанию — 10M). Стратегия ParamPack относится к упаковке и отправке градиента, соответствующего параметрам, сокращая отправку небольших пакетов, чтобы уменьшить задержку связи и увеличить использование полосы пропускания.

2) Фактический тренировочный эффект

Продолжая пример обучения ResNet50 с 8 картами, обратное время SHM почти на 30 мс (203 мс -> 174 мс) быстрее, чем у NCCL.

图10(使用 SHM 后端进行 ResNet50 8卡训练)

Недостатки разделяемой памяти AllReduce/последующие улучшения

1) высокая загрузка ЦП

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

2) Дополнительные расходы на связь

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

3) Многопроцессорная балансировка нагрузки

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

4) Больше совпадений

В настоящее время используется только перекрытие между copy и reduce, но на самом деле могут перекрываться и копии h2d и d2h, что можно дополнительно ускорить.


Прикрепил:

Гитхаб:MegEngine Тяньюань

Официальный сайт:MegEngine — глубокое обучение, простая разработка

Добро пожаловать в группу технической биржи MegEngine QQ: 1029741705