TensorFlow自定义训练循环使用GPU运行速度慢于CPU问题咨询
问题原因分析
- 数据/计算量过小,数据拷贝开销占主导:你当前的
batchSize只有100,网络结构也非常小(3层全连接每层8个神经元),GPU本身适合大批次、大计算量的并行任务,现在每次训练步需要把小批量数据从内存拷贝到显存、再把结果传回来的开销,远大于GPU并行计算节省的时间,反而比直接在CPU计算更慢。你提到测试过更复杂的模型问题仍然存在,大概率是调整后的模型计算量仍未达到GPU的并行阈值,只要跨设备开销仍高于计算节省的时间,速度就会比CPU慢。 - 自定义计算逻辑的GPU适配损耗:你代码里的HJB方程实现用到了多次
tf.gradients、tf.pow、逐元素运算,这些小算子在GPU上运行的调度开销本身就比CPU高,小批量下没有办法把GPU的计算核心占满,核心大部分时间在空载等待调度,反而效率低。 - 频繁的CPU-GPU数据交互:你训练循环里每一步都调用
loss.numpy()把损失值从显存转回CPU存到列表里,10万次迭代就对应10万次跨设备数据传输,这部分额外开销在GPU场景下会被放大,CPU场景下根本没有跨设备传输的成本,自然更快。
优化方案
- 调大批次规模:把
batchSize从100至少调到1024甚至更大,优先把GPU的计算核心占满,抵消数据拷贝的开销,让GPU的并行优势发挥出来。 - 减少跨设备数据传输频率:不要每一轮都把loss转成numpy存到列表,改成每100/1000轮才取一次loss值统计,大幅减少跨设备交互次数。
- 合并小算子计算:把HJB函数里的逐元素小运算尽量合并成向量/矩阵运算,减少GPU的算子调度次数。
- 显式指定张量运行设备:给所有常量、输入张量显式指定
/device:GPU:0,避免TensorFlow自动调度时反复在CPU和GPU之间切换设备,增加额外开销。 - 调高模型并行度:如果测试更复杂的模型,可以把每层神经元数从8调到256以上,层数增加到5-10层,模型计算量上去后GPU的优势会非常明显。
内容的提问来源于stack exchange,提问作者rrmaura
相关产品推荐
相关产品推荐

