【发布时间】:2019-04-23 23:59:15
【问题描述】:
我们正在为三元组训练推荐系统的网络。 fit方法的核心代码如下:
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。但是,在 GPU 中运行 fit 并不比在 CPU 中运行快多少。此外,将batch_size 从 50000 增加到 500000 会使每批次的时间增加 10 倍(考虑到 GPU 并行化,这是我没想到的)。
具体来说,对于 50k 批次:
* output = self.model(batch.data[0]) 在 GPU 上耗时 0.03 秒,在 CPU 上耗时 0.08 秒。
* loss.backward() 耗时 0.11 秒,CPU 耗时 0.39。
两者都使用nd.waitall() 进行评估,以避免异步调用导致错误测量。
此外,在普通 MXNet 上运行的非常相似的代码在相应部分上花费的时间不到 0.03 秒,这导致一个完整的 epoch 需要从 MXNet 略高于 1 分钟的时间到 Gluon 的 15 分钟。
对这里可能发生的事情有什么想法吗?
提前致谢!
【问题讨论】:
标签: mxnet