мы тренируем сеть для рекомендательной системы, по триплетам. Основной код для метода подбора следующий:
for e in range(epochs):
start = time.time()
cumulative_loss = 0
for i, batch in enumerate(train_iterator):
# Forward + backward.
with autograd.record():
output = self.model(batch.data[0])
loss = loss_fn(output, batch.label[0])
# Calculate gradients
loss.backward()
# Update parameters of the network.
trainer_fn.step(batch_size)
# Calculate training metrics. Sum losses of every batch.
cumulative_loss += nd.mean(loss).asscalar()
train_iterator.reset()
где train_iterator
- это пользовательский класс итератора, который наследует от mx.io.DataIter
и возвращает данные (тройки) уже в соответствующем контексте, как:
data = [mx.nd.array(data[:, :-1], self.ctx, dtype=np.int)]
labels = [mx.nd.array(data[:, -1], self.ctx)]
return mx.io.DataBatch(data, labels)
self.model.initialize(ctx=mx.gpu(0))
также вызывался перед запуском метода fit
. loss_fn = gluon.loss.L1Loss()
.
Проблема в том, что nvidia-smi
сообщает, что процесс правильно распределен в GPU. Однако запуск fit
в графическом процессоре не намного быстрее, чем запуск в процессоре. Кроме того, увеличение batch_size
с 50000 до 500000 увеличивает время на пакет в 10 раз (чего я не ожидал, учитывая распараллеливание GPU).
В частности, для партии 50 КБ:
* output = self.model(batch.data[0])
занимает 0.03 секунды на GPU и 0.08 на CPU.
* loss.backward()
занимает 0,11 секунды и 0,39 на процессоре.
оба оцениваются с помощью nd.waitall()
, чтобы избежать асинхронных вызовов, приводящих к неправильным измерениям.
Кроме того, очень похожему коду, который выполнялся на простом MXNet, потребовалось менее 0,03 секунды для соответствующей части, что приводит к полной эпохе, занимающей чуть более минуты с MXNet, до 15 минут с Gluon.
Есть идеи о том, что здесь может происходить?
Заранее спасибо!