Проблема с производительностью Theano при копировании данных на GPU

У меня были некоторые проблемы с производительностью при попытке обучить глубокую свёрточную нейронную сеть с использованием теано и лазаньи. Я провел несколько экспериментов, чтобы выяснить, откуда они берутся. Одна вещь, которую я обнаружил, заключается в том, что загрузка пакетов изображений из основной памяти в графический процессор занимает очень много времени. Вот минимальный пример, иллюстрирующий проблему. Это просто умножает, сколько времени требуется для оценки функции анонимной идентичности для пакетов изображений с размерами пакетов 1,2,4,8,16,... Я работаю с изображениями RGB размером 448x448.

import numpy as np
import theano
import theano.tensor as T
import time

var = T.ftensor4('inputs')
f = theano.function([var], var)

for batchsize in [2**i for i in range(6)]:
    X = np.zeros((batchsize,3,448,448), dtype=np.float32)
    print "Batchsize", batchsize
    times = []
    start = time.time()
    for i in range(1000):
        f(X)
        times.append(time.time()-start)
        start = time.time()
    print "-> Function evaluation takes:", np.mean(times), "+/-", np.std(times), "sec"

Мои результаты следующие:

Batchsize 1
-> Function evaluation takes: 0.000177580833435 +/- 2.78762612138e-05 sec
Batchsize 2
-> Function evaluation takes: 0.000321553707123 +/- 2.4221262933e-05 sec
Batchsize 4
-> Function evaluation takes: 0.000669012069702 +/- 0.000896798280943 sec
Batchsize 8
-> Function evaluation takes: 0.00137474012375 +/- 0.0032982626882 sec
Batchsize 16
-> Function evaluation takes: 0.176659427643 +/- 0.0330068803715 sec
Batchsize 32
-> Function evaluation takes: 0.356572513342 +/- 0.074931685704 sec

Обратите внимание на увеличение коэффициента 100 при увеличении размера партии с 8 до 16. Это нормально или у меня какие-то технические проблемы? Если да, то есть ли у вас какие-либо идеи, откуда он мог взяться? Любая помощь приветствуется. Также было бы полезно, если бы вы запустили фрагмент кода и сообщили об увиденном.

РЕДАКТИРОВАТЬ: Даниэль Реншоу указал, что это, вероятно, не имеет ничего общего с копированием хост-GPU. Любые другие идеи, откуда может возникнуть проблема? Еще немного информации:

Отладочная печать theano функции гласит:

DeepCopyOp [@A] 'inputs'   0
 |inputs [@B]

Результат профилирования theano:

Function profiling                                                      
================== 
Message: theano_test.py:14
Time in 6000 calls to Function.__call__: 3.711728e+03s
Time in Function.fn.__call__: 3.711528e+03s (99.995%)                       
Time in thunks: 3.711491e+03s (99.994%)
Total compile time: 6.542931e-01s
    Number of Apply nodes: 1
    Theano Optimizer time: 7.912159e-03s
        Theano validate time: 0.000000e+00s
    Theano Linker time (includes C, CUDA code generation/compiling): 8.321500e-02s
        Import time 2.951717e-02s

Time in all call to theano.grad() 0.000000e+00s
Class 
---

<% time> <sum %> <apply time> <time per call> <type> <#call> <#apply> <Class name>
100.0%   100.0%     3711.491s       6.19e-01s     C     6000       1   theano.compile.ops.DeepCopyOp
... (remaining 0 Classes account for   0.00%(0.00s) of the runtime)

Ops
---
<% time> <sum %> <apply time> <time per call> <type> <#call> <#apply> <Op name>
100.0%   100.0%     3711.491s       6.19e-01s     C     6000        1   DeepCopyOp
... (remaining 0 Ops account for   0.00%(0.00s) of the runtime)

Apply
------
<% time> <sum %> <apply time> <time per call> <#call> <id> <Apply name>
100.0%   100.0%     3711.491s       6.19e-01s   6000     0 DeepCopyOp(inputs)
... (remaining 0 Apply instances account for 0.00%(0.00s) of the runtime)

INFO (theano.gof.compilelock): Waiting for existing lock by process '3642' (I am process '22124')
INFO (theano.gof.compilelock): To manually release the lock, delete /home/bal8rng/.theano/compiledir_Linux-3.16--generic-x86_64-with-debian-jessie-sid-x86_64-2.7.10-64/lock_dir

ТЕАНО_ФЛАГС: floatX=float32,device=gpu,optimizer_including=conv_meta,mode=FAST_RUN,blas.ldflags="-L/usr/lib/openblas-base -lopenblas",device=gpu3,assert_no_cpu_op=raise


person lballes    schedule 10.11.2015    source источник
comment
Что касается вашего обновленного вопроса, вас это действительно волнует? Не было бы более плодотворным исследовать характеристики производительности более осмысленных вычислений? Или вы уже определили, что такое поведение вызывает у вас проблемы и в более реальных ситуациях?   -  person Daniel Renshaw    schedule 14.11.2015


Ответы (1)


Ваши вычисления почти наверняка не выполняются на графическом процессоре! Пока вы используете стандартные флаги конфигурации, оптимизатор Theano достаточно умен, чтобы убедитесь, что на самом деле никакие операции не выполняются, поэтому он не добавляет никаких операций «переместить данные в графический процессор» и «переместить данные обратно из графического процессора» в скомпилированные вычисления. Вы можете увидеть это, добавив следующую строку сразу после строки f = theano.function([var], var).

theano.printing.debugprint(f)

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

Тем не менее, любопытно, что вы получаете результаты, которые вы делаете. Если бы вычисление действительно выполнялось на ЦП, я бы все равно не ожидал увидеть такое ступенчатое изменение по мере увеличения размера пакета. Это, вероятно, мало вас интересует, если вы не продолжаете наблюдать такое же поведение, когда вычисления фактически выполняются на графическом процессоре.

Кстати, запустив ваш код (который на моем сервере фактически работал на ЦП, несмотря на device=gpu в конфигурации, как объяснялось выше), я не получил такого же огромного пошагового изменения; мои множители времени были 2,6, 1,9, 4,0, 3,9, 2,0 (т.е. время увеличилось в 2,6 раза от размера партии = 1 до размера партии = 2 и т. д.)

person Daniel Renshaw    schedule 11.11.2015