Автор: Цао Бин | Архитектор 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 мс:
Давайте посмотрим на обратное время обучения с 8 картами, которое увеличилось до 203 мс, что на 39 мс больше, чем в случае с одной картой:
Действительно, время назад стало намного длиннее, но почему? Можем ли мы его устранить?
1) почему
Одним словом: NCCL AllReduce занимает вычислительные ресурсы cuda, поэтому вычисления становятся медленнее.
Конкретная причина состоит в том, что ядро Cuda, соответствующее NCCL Allredu, нуждается в связи, так и расчета, которые занимают расчет ресурсов расчета, но большую часть времени находится в связи, что приводит к высокой скорости утилизации вычислительных ресурсов.
2) Можно ли его устранить
Конечно, это возможно, вычисление cuda и связь могут быть распараллелены, и вычисление и связь могут выполняться параллельно на двух разных потоках cuda.документация разработчика cudaупомянул.
3) Пример реальных тестовых вычислений и коммуникационного параллелизма
Stream0 выполняет умножение матриц, stream1 выполняет копирование, и на скорость умножения матриц до и после это не влияет:
Реализовать идеи
Вот два метода реализации AllReduce.
1) Уменьшить разброс + Все собрать
Ring AllReduce использует режим ReduceScatter + AllGather: сначала первый раунд связи вычисляет частичную сумму на каждом узле, а затем второй раунд связи собирает частичную сумму для получения окончательного результата.
2) Уменьшить + Трансляция
Метод Reduce + Broadcast похож на Parameter Server, который сначала вычисляет полную совокупную сумму на одном узле, а затем передает ее на каждый узел.
В новом алгоритме используется метод Reduce + Broadcast: сначала все данные копируются на процессор (используя Shared Memory), затем процессор накапливает их, а затем копирует обратно на GPU.
Поскольку прямое накопление копий не перекрывает вычисления и обмен данными, мы также приняли блочную стратегию, аналогичную Ring AllReduce, чтобы полностью перекрыть обмен данными и вычисления, как показано на следующем рисунке.
Поскольку используется общая память, этот бэкенд сокращенно называется SHM.
добиться эффекта
1) Производительность оператора
По сравнению с NCCL, SHM имеет немного большую задержку и меньшую пропускную способность и может достигать примерно 90% производительности NCCL, когда объем данных больше.
Производительность SHM необходимо задействовать в случае больших пакетов данных, и стратегия ParamPack может максимизировать эффект SHM (стратегия ParamPack используется в Distributed.make_allreduce_cb в MegEngine, а размер пакета по умолчанию — 10M). Стратегия ParamPack относится к упаковке и отправке градиента, соответствующего параметрам, сокращая отправку небольших пакетов, чтобы уменьшить задержку связи и увеличить использование полосы пропускания.
2) Фактический тренировочный эффект
Продолжая пример обучения ResNet50 с 8 картами, обратное время SHM почти на 30 мс (203 мс -> 174 мс) быстрее, чем у NCCL.
Недостатки разделяемой памяти AllReduce/последующие улучшения
1) высокая загрузка ЦП
Поскольку ресурс ЦП занят операцией уменьшения, она будет работать медленнее, когда ресурсы ЦП ограничены, и перед ее использованием необходимо определить, достаточно ли ресурсов ЦП.
2) Дополнительные расходы на связь
Поскольку существует зависимость данных между копированием и сокращением, для запуска копирования необходимо дождаться завершения предыдущего сокращения, а для уменьшения необходимо дождаться, пока данные копии будут на месте перед запуском, поэтому синхронизация семафора вставляется в середина, что вносит дополнительные расходы на связь, чем больше блоков, тем очевиднее ситуация.
3) Многопроцессорная балансировка нагрузки
Непоследовательное копирование и снижение скорости каждого процесса приводят к проблеме асинхронного выполнения, что приводит к дополнительному времени ожидания.Назначение задач в соответствии с фактической скоростью выполнения еще больше улучшит производительность.
4) Больше совпадений
В настоящее время используется только перекрытие между copy и reduce, но на самом деле могут перекрываться и копии h2d и d2h, что можно дополнительно ускорить.
Прикрепил:
Гитхаб:MegEngine Тяньюань
Официальный сайт:MegEngine — глубокое обучение, простая разработка
Добро пожаловать в группу технической биржи MegEngine QQ: 1029741705