Мне было интересно, сможет ли кто-нибудь посоветовать, как получить максимальную производительность из тензорного потока в настройке 4 GPU.
В качестве теста я создал две из той же сети (остаточная сеть 18-го уровня с небольшими банками фильтров (от 16 до 128) на 32х32 входах. Размер партии 512, 128 на графический процессор.). Один в MXNet и один, который я смоделировал начальный пример.
Моя сеть MXNet может обучаться примерно в 7 тыс. примеров в секунду, где тензорный поток способен только 4,2 тыс. с фиктивными данными и 3,7 с реальными данными.
(при запуске на 1 графическом процессоре число составляет 1,2 тыс. примеров в секунду против 2,1 тыс.)
В моем эксперименте у меня есть несколько вопросов в надежде ускорить процесс.
-
Использование GPU кажется довольно низким при обучении. Я заметил, что в белой бумаге tensorflow есть поддержка для запуска нескольких потоков на одном GPU. Возможно ли это в публичном выпуске?
-
Есть ли способ выполнить несколько операций поезда в одном выполнении
session.run()
? Или выполнить асинхронное выполнение? Это позволило бы обновлять весы одновременно с прохождением следующих партий? Я попытался использовать 2 потока (как для системы, так и дляQueueRunners
), но это только привело к замедлению. MXNet может увеличить скорость за счет загрузки обновлений веса на CPU, чтобы gpu можно было использовать для следующей партии. -
Будет ли новое распределенное время выполнения обходить некоторые из этих проблем, разрешив мне запустить более одного рабочего на одной машине?
-
Есть ли что-то еще, что можно сделать?
Я знаю, что здесь есть несколько подобных вопросов при переполнении стека, но, хотя в моем поиске я не смог найти решение своих проблем, которые я еще не пробовал.
Edit:
Я сделал немного профилирования CUDA, чтобы посмотреть, что такое дорогие ядра. По моему прогону, 21,4% времени тратится внутри:
void Eigen::internal::EigenMetaKernel_NonVectorizable<Eigen::TensorEvaluator
<Eigen::TensorAssignOp<Eigen::TensorMap<Eigen::Tensor<float, int=4, int=1, long>, int=16>,
Eigen::TensorPaddingOp<Eigen::array<std::pair<int, int>,
unsigned long=4> const, Eigen::TensorMap<Eigen::Tensor<float const,
int=4, int=1, long>, int=16> const > const > const, Eigen::GpuDevice>, long>(float, int=4)
и 20,0% времени были потрачены на
void Eigen::internal::EigenMetaKernel_NonVectorizable<Eigen::TensorEvaluator
<Eigen::TensorAssignOp<Eigen::TensorMap<Eigen::Tensor<float, int=4, int=1, long>, int=16>,
Eigen::TensorBroadcastingOp<Eigen::array<int, unsigned long=4>
const, Eigen::TensorMap<Eigen::Tensor<float const, int=4, int=1, long>,
int=16> const > const > const, Eigen::GpuDevice>, long>(float, int=4)
Выключить подпись Я не совсем уверен, что они делают. Имеют ли они смысл?
В дополнение к этому, анализ сообщает о низком ядре concurrency, 0%, как и ожидалось. И низкое использование вычислений - 34,9% (это включает время запуска и немного питона в контуре поезда. Примерно 32 секунды всего из 91. Это происходит примерно до 50% использования в тензорном потоке.)
Изменить 2:
Я прикрепил копию обрезанного исходного кода. В целом, хотя меня больше волнует вопрос 1-3 и не хочу брать слишком много времени вовремя.
Кроме того, я запускаю тензорный поток, построенный из: f07234db2f7b316b08f7df25417245274b63342a
Изменить 3:
Обновлен до последнего tensorflow (63409bd23facad471973b110df998782c0e19c06) того же кода, формат данных по умолчанию (NHWC), и это, казалось, ускорило это. На поддельные данные 6.7k-6.8k (термическая зависимость я думаю?) Примеры второй 4gpu. 1gpu - 2.0k примеры в секунду. Реальная производительность данных составляет около 4.9k примеров в секунду для 4gpu. 1gpu - 1.7k примеров в секунду.
Изменить 4:
Кроме того, я попробовал преобразовать форматы данных в BCHW. Я сделал преобразование, смоделированное с помощью тестов Soumith. Свертки были действительно быстрее, но, конечно, периодическая норма, которая, по-видимому, все испортила. Используя наивную реализацию (фиксируя ось и делая весы [1, C, 1,1] вместо [C]), я могу получить только 1,2k примеров второй - на 4 gpu (поддельные данные). Где, как и с транспозицией до и после нормы партии, я могу получить 6.2k примеры второй (поддельные данные). Все еще медленнее, чем данные NHWC data_format.