Tensorflow模型GPU使用率低的问题

任务管理器显示Tensorflow模型GPU使用率低

前几天自己跑模型的时候遇到一个问题,就是发现自己在任务管理器上面显示的GPU使用率很低,如下图所示:
Tensorflow模型GPU使用率低的问题_第1张图片
任务管理器显示的一直是4%的GPU使用率,这个时候就很让人疑惑了,因为我跑的是一个GANs模型,而且鉴别器我加入了一个DenseNet(这个全是密集连接的卷积神经网络),不可能调不出来GPU的使用的,而且CPU的使用率也这么低,模型是可以运行的,就证明GPU应该是用上了,查了很多,终于是查出来问题了。

直接在cmd中查看自己的GPU使用情况

#输入 3表示每过3秒更新一下你的GPU使用情况
nvidia-smi -l 3

Tensorflow模型GPU使用率低的问题_第2张图片
这边可以直接看到,我的GPU利用率是93%,温度62℃,内存使用是5738/6144 MiB。
也就是我的模型在运行的时候是用到了GPU的,而且使用率还很高。
那么我们就要来找原因了,为什么任务管理器显示的很低呐。

Windows 10任务管理器里面的GPU占用率到底是怎么算的?

我在维基百科里面看到一个解释的还算很不错的帖子,上面是这样说的:
首先开发者给我们讲述了任务管理器是怎么得知GPU的占用情况的。在Windows 10上面,GPU通过Windows Display Driver Model(WDDM,Windows显示驱动模型)抽象,它的核心——图形内核——负责抽象、管理和在所有进程分配GPU资源。它含有一个GPU事务器(VidSch)和一个视频内存管理器(VidMem),前者负责将GPU的各种引擎分配给想要使用它们的进程,并对访问进行仲裁和优先级排序,后者则是负责管理GPU可调用的内存——包括专用的显存和共享的系统内存。任务管理器就是通过VidSch和VidMem回报的数据来计算GPU的使用情况的,这样一来,不管程序使用了什么API(DX、OpenGL、OpenCL,甚至CUDA、Mantle这种专有API都可以监控),它都能准确地收集GPU的占用情况,另外由于两者是实际负责分配GPU资源的,位于驱动层面,它们回报数据的精准度也要比很多第三方工具要高,使得任务管理器有很高的精度。
既然有很高的精度,那它为什么还是报不准我的GPU占用率呢?这就牵扯到另一个问题,GPU引擎。
现代GPU上除了有主要用于图形、通用计算的统一计算单元外,还会集成一些其他的电路,比如说,用于视频编解码的专用模块。它们之间的关系一般是并行的,GPU可以同时运行图形计算和视频编码任务,在驱动层面,这些不同的模块就被抽象为不同的Engine,也就是引擎,比如说一个典型的GPU可以有以下这些引擎:
在具体执行任务的时候,不同的任务会在不同的引擎上面执行,比如说我打游戏,就用到3D引擎;我用显卡加速Premiere Pro,就用到CUDA引擎;我用NVENC编码视频,就用到视频编码引擎。
其实后面还有内容,感兴趣的人可以自己去查一下,应该很多博客都有转载这个帖子,那么我们可以直接从上面的那段话思考。打游戏,就用到3D引擎;显卡加速Premiere Pro,就用到CUDA引擎。而Tensorflow模型GPU是使用CUDA的,那么也就是说,我们要关注的点在于CUDA

Tensorflow模型GPU是使用CUDA的

按照这个思路,把任务管理器上的3D、Copy、Video Encode、Video Decode全部切换为Cuda,发现破案了!!!
Tensorflow模型GPU使用率低的问题_第3张图片
其实Cuda是拉满的,而且GPU的使用率已经就不再是显示4%,也就是说,我们是思路是对的,对于Tensorflow模型GPU的使用率,不应该是单纯的看任务管理的上的显示。而是应该按照 nvidia-smi -l 3 的方法,直接查看最为准确。

深度学习提高模型GPU使用率的方法

这里再推荐几个DeepLearn 提高模型GPU使用率的方法
(1)增加batch size,增加GPU的内存占用率,这个是最直接的,可以根据内存使用情况去增加;
(2)在PyTorch这个框架里面,数据加载Dataloader上做更改和优化,包括num_workers(线程数),pin_memory,会提升速度。将num_workers线程数设置稍微大一点,推荐是8,16等,且开启pin_memory=True。(这个方法我还没去验证,因为我近期用的比较多的都是keras);
(3)Tensorflow 的话,有看到说把数据从float 类型转变为tensor 放入模型能加速的,这个也有一定根据,就是减少CPU在数据预处理和读取上的使用,增加GPU的利用;
(4)和(3)类似,推荐直接 tf.data.Dataset.from_tensor_slices 来预处理数据,我感觉是不好用,但是看到有的博客推荐。

总结

最后,总结一下就是,得先确保Tensorflow模型GPU使用率是不是真的低,比如我的情况就不是,是任务管理器计算利用率的问题。如果是真的低,那就推荐这几个方法可以尝试一下,个人感觉增加batch size的方法是最好用的。

你可能感兴趣的:(tensorflow,windows,python)