вывод линейной модели по тензорному потоку на GPU медленный - PullRequest
0 голосов
/ 17 мая 2018

Я тренирую модель разреженной логистической регрессии на тензорном потоке. Эта проблема конкретно о выводной части. Я пытаюсь сделать вывод о производительности на процессорах и графических процессорах. Я использую графический процессор Nvidia P100 (4 матрицы) на моем текущем GCE. Я новичок в GPU, так что извините за наивные вопросы.

Модель довольно большая ~ 54 тыс. Операций (считается ли она большой по сравнению с моделями dnn или imagenet?). Когда я регистрирую размещение устройства, я вижу только использование gpu: 0, а остальные не используются? Я не делаю никаких устройств во время обучения, но во время вывода я хочу, чтобы он оптимально размещал и использовал gpu. Несколько вещей, которые я заметил: мой входной узел placehoolder (feed_dict) помещен в процессор, поэтому я предполагаю, что мои данные копируются из процессора в gpu? как feed_dict точно работает за сценой?

1) Как я могу разместить свои данные, для которых я хочу запустить прогнозирование непосредственно в GPU? Примечание: мое обучение выполняется на распределенном процессоре с несколькими терабайтами, поэтому у меня не может быть постоянной или переменной непосредственно в моем графике во время обучения, но по моему выводу у меня, безусловно, могут быть небольшие партии данных, которые я бы хотел разместить непосредственно в gpu. Есть ли способы, которыми я могу достичь этого? 2) Поскольку я использую P100 GPU, я думаю, что он имеет объединенную память с хостом, возможно ли иметь zerocopy и напрямую загружать мои данные в GPU? Как я могу сделать это из кода Python, Java и C ++. В настоящее время я использую feed_dict, который из различных источников Google, я думаю, не совсем оптимален. 3) Есть ли какой-нибудь инструмент или профилировщик, который я могу использовать, чтобы увидеть, когда я набираю код профиля, например:

for epoch_step in epochs:
    start_time = time.time()
    for i in range(epoch_step):
            result = session.run(output, feed_dict={input_example: records_batch})
    end_time = time.time()
    print("Batch {} epochs {} :time {}".format(batch_size, epoch_step, str(end_time - start_time)))

сколько времени тратится на 1) передачу данных с процессора на gpu 2) накладные расходы на запуск сеанса 3) использование gpu (в настоящее время я периодически использую nvidia-smi для мониторинга 4) издержки вызова ядра на процессоре vs gpu (я предполагаю, что каждый вызов sess.run вызывает 1 вызов ядра, верно?

мои текущие результаты: Процессор:

Batch size : 10
NumberEpochs   TimeGPU    TimeCPU 
10             5.473      0.484
20             11.673     0.963
40             22.716     1.922
100            56.998     4.822
200            113.483    9.773

Batch size : 100
NumberEpochs   TimeGPU    TimeCPU 
10             5.904      0.507
20             11.708     1.004
40             23.046     1.952
100            58.493     4.989
200            118.272    9.912

Batch size : 1000 
NumberEpochs   TimeGPU    TimeCPU   
10             5.986      0.653
20             12.020     1.261
40             23.887     2.530
100            59.598     6.312
200            118.561    12.518

Batch size : 10k
NumberEpochs   TimeGPU    TimeCPU 
10             7.542      0.969
20             14.764     1.923
40             29.308     3.838
100            72.588     9.822
200            146.156    19.542

Batch size : 100k
NumberEpochs   TimeGPU    TimeCPU 
10             11.285     9.613
20             22.680     18.652
40             44.065     35.727
100            112.604    86.960
200            225.377    174.652

Batch size : 200k
NumberEpochs   TimeGPU    TimeCPU 
10             19.306     21.587
20             38.918     41.346
40             78.730     81.456
100            191.367    202.523
200            387.704    419.223

Некоторые заметные наблюдения: По мере увеличения размера пакета я вижу увеличение использования моего графического процессора (достигает 100% для единственного графического процессора, который он использует, есть ли способ, которым я могу сказать tf использовать другой графический процессор тоже) при размере партии 200 Кб - единственный раз, когда я вижу, что мой наивный бенчмаркинг показывает, что у gpu есть небольшой выигрыш по сравнению с процессором. Увеличение размера партии для данной эпохи оказывает минимальное влияние на время как для процессоров, так и для процессоров, пока размер партии не будет <= 10k. Но после этого увеличения размера партии с 10k -> 100k -> 200k время также увеличивается довольно быстро, т. Е. Для данной эпохи, скажем, 10, размер пакета 10, 100, 1k, 10k, время процессора и процессор остаются довольно стабильными ~ 5- 7 секунд для графического процессора и 0,48-0,96 секунд для процессора (что означает, что sess.run имеет намного больше служебных данных, чем вычисление самого графика?), Но при увеличении размера пакета дальнейшее время вычисления увеличивается гораздо быстрее, т.е. для эпохи 10 100k-> 200k gputime увеличился с 11 до 19 секунд и время процессора также удваивается, почему так? Кажется, для большего размера партии, хотя у меня есть только один sess.run, но внутренне он разбивает это на меньшую партию и вызывает sess.run дважды, потому что размер партии 20k эпохи 20k более близко соответствует партии эпохи 10 200k ..

Как я могу улучшить мой вывод дальше, я считаю, что я не использую все процессоры оптимально. Есть ли какие-либо идеи относительно того, как лучше тестировать, чтобы получить более точные расчеты времени для передачи процессора> gpu и фактического ускорения вычислений графов при переходе с процессора на графический процессор? Загрузка данных лучше напрямую, если это возможно, нулевое копирование в gpu? Могу ли я разместить некоторые узлы в gpu только во время вывода, чтобы получить лучшую производительность? Идеи вокруг квантования или оптимизации графа вывода?

Есть еще идеи по улучшению вывода на основе графического процессора. Может быть, оптимизация на основе xla или тензор? Я хочу иметь высокопроизводительный код логического вывода для выполнения этих вычислений на GPU, в то время как сервер приложений работает на CPU.

1 Ответ

0 голосов
/ 17 мая 2018

Одним из источников информации являются документы TensorFlow по производительности, включая Оптимизация для графических процессоров и Высокопроизводительные модели .

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

Я отмечу, что, если вы не используете DistributionStrategy, TensorFlow не будет автоматически назначать операции более чем на один графический процессор ( source .GPU (если вы регистрируете размещение устройства, есть вероятность, что поиск выполняется на CPU).Модель логистической регрессии имеет только (разреженный) входной слой и выходной слой, поэтому, как правило, математических операций очень мало.Графические процессоры превосходят большинство, когда они выполняют много матричных умножений, сверток и т. Д.

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

...