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

В репозитории MXNet есть приятный скрипт, давайте сразу воспользуемся им.

python train_imagenet.py --network resnet --num-layers 50 \
--gpus 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 \
--data-train /data/im2rec/imagenet_training.rec \
--data-val /data/im2rec/imagenet_validation.rec

Достаточно просто. Насколько быстро это работает?

Примерно 400 изображений в секунду, что означает примерно 53 минуты за эпоху. Более трех с половиной дней за 100 эпох. Да ладно, мы не хотим ждать так долго. Подумайте, подумайте ... Разве мы не читали где-нибудь, что больший размер пакета ускорит обучение и поможет модели лучше обобщить? Давайте в этом разберемся :)

Выбор самого большого размера партии

В этом контексте наибольший размер пакета означает наибольший размер, который уместится на одном из наших графических процессоров: каждый из них имеет 11439 МБ ОЗУ.

Используя команду nvidia-smi, мы видим, что текущее обучение использует только около 1500 МБ. Поскольку мы не передали нашему скрипту параметр размера пакета, он использует значение по умолчанию 128. Это совершенно неэффективно.

Методом проб и ошибок мы можем быстро определить, что максимально возможный размер пакета - 1408. Давайте попробуем.

python train_imagenet.py --network resnet --num-layers 50 \
--gpus 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 \
--data-train /data/im2rec/imagenet_training.rec \
--data-val /data/im2rec/imagenet_validation.rec \
--batch-size 1408

Это больше похоже на то, что ОЗУ графического процессора исчерпано. Скорость тренировки должна быть намного выше… не так ли?

Неа. Что-то точно не так. Давай снимем капюшон.

Обнаружение остановленных графических процессоров

Оперативная память графического процессора используется полностью, но как насчет реальных ядер графического процессора? Оказывается, есть простой способ узнать. Давайте посмотрим на «изменчивую информацию о графическом процессоре», возвращаемую nvidia-smi, это даст нам представление о том, как на самом деле работают графические процессоры.

Это не хорошо. В одну секунду наши графические процессоры работают на 100%, а в следующую - простаивают.

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

Масштабирование процесса Python

Файлы RecordIO, в которых хранится обучающий набор, размещаются на томе EBS (созданном из моментального снимка, как объяснялось ранее). Наш скрипт Python считывает изображения, используя значение по умолчанию в 4 потока. Затем он выполняет на них увеличение данных (изменение размера, изменение соотношения сторон и т. Д.), Прежде чем передавать их в графические процессоры. Вероятно, узкое место здесь.

Время простоя чрезвычайно велико (id = 80,5%), но ожидания ввода-вывода отсутствуют (wa = 0%). Похоже, эта система просто недостаточно усердно работает. P2.16xlarge имеет 64 виртуальных ЦП, поэтому давайте добавим потоки декодирования.

python train_imagenet.py --network resnet --num-layers 50 \
--gpus 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 \
--data-train /data/im2rec/imagenet_training.rec \
--data-val /data/im2rec/imagenet_validation.rec \
--batch-size 1408 --data-nthreads=32

Стрельба по всем шестнадцати

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

А как насчет нашего процесса Python?

Он также работает усерднее, поскольку все 32 потока работают параллельно. Тем не менее, ожидания ввода-вывода по-прежнему не видно (спасибо EBS). Фактически, у нас, кажется, есть хороший запас прочности, когда дело доходит до ввода-вывода: мы, безусловно, могли бы добавить больше потоков для поддержки большего размера пакета или более быстрых графических процессоров, если бы они у нас были.

А как насчет скорости тренировки? Это приятно, стабильно 700+ изображений в секунду. Это на 75% больше по сравнению с тем, с чего мы начали, поэтому, безусловно, стоило изменить.

Эпоха завершится за 30 минут, что дает нам чуть больше 2 дней из 100 эпох. Не так уж плохо.

Оптимизация стоимости

По цене по запросу в us-east-1 50 часов обучения обойдутся нам в 720 долларов. Ой. Конечно, мы можем это оптимизировать?

Давайте посмотрим на спотовые цены для p2,16xlarge. Они сильно различаются от региона к региону, но вот что я нашел в us-west-2 (подсказка: использование API describe-spot-price должно помочь вам очень быстро найти хорошие предложения).

Да, дамы и господа. Это 89% скидка. Обучение теперь будет стоить примерно 80 долларов.

Вывод

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

В следующем посте, я думаю, мы рассмотрим обучение ImageNet с Керасом, но я еще не совсем уверен: D

Как всегда, спасибо за чтение.

Поздравляем, если вы уловили отсылку к Бильбо в названии. Ты настоящий толкин-ботаник;)