1 运行环境
python3.7 + mxnet-cu101 1.5.0
2 现象
无论是用pycharm还是在windows命令行中启动.py,都很慢。调试时发现主要是在import mxnet这一句。
3 查资料
网上说是因为dll文件大(检查了一下文件大小,发现libmxnet.dll约200MB,cudnn64_7.dll高达400MB!的确很大),加载慢,并提供了方法:一是按自己的显卡编译缩小dll体积(应该是编译mxnet),二是把python和cuda放到固态硬盘上。
我对这个说法感到疑惑——win10不是有预取机制吗?第一次加载这些dll很慢,第二次是不是就用不着了?
4 实践研究
4.1 可能原因研究:dll文件大
单独编一个.py测试:
import time
start = time.perf_counter()
import mxnet
end = time.perf_counter()
print(f"Elapsed time: {end - start:.6f} seconds")
python和cuda放在机械硬盘上的测试结果:Elapsed time: 11.831467 seconds
python和cuda放在ssd,重新测试,import mxnet的耗时没有改观,仍然是11.8s。无论是否重启系统。
果然印证了我的疑惑,不是dll文件大的问题。本来还想研究一下dll预加载问题,看来也用不着了。
4.2 比较确信的原因:mxnet自身的问题
现在应该可以确信是mxnet自身的问题了。查了查相关资料,一般的说法都是要重新编译mxnet。
其中一个说法是:构建时使用 USE_CUDNN=1
。一般能提速 50+%。在运行前执行 export MXNET_CUDNN_AUTOTUNE_DEFAULT=1
。一般能提速 10%-15%。
因为重构比较麻烦,暂时没有尝试。
5 解决办法
有两个办法:
1)重新编译GPU版本的mxnet。这个一般情况就不用考虑了,比较耗费精力。
2)正式训练神经网络用GPU版本,调试用CPU版本。
GPU版本启动要10s,CPU版本启动只需要1s。调试时要频繁重新启动,故先用CPU版本检查代码问题。正式训练神经网络耗时很长,不在乎启动的这10s,所以用GPU版本。
那么,如何在CPU版本和GPU版本切换呢?用python虚环境。一个虚环境用CPU版本,一个虚环境用GPU版本。
一点提醒
记得设置context:
ctx = mx.gpu() if mx.context.num_gpus() else mx.cpu()
mlp_model = mx.mod.Module(symbol=fully_connected_layer, context=ctx, label_names=['linea_label'])
我之前因为没设置这个,发现GPU版本和CPU版本训练速度差不多,追查了半天,才发现GPU版本根本就没有启用CUDNN嘛!