最近使用github上的一个开源项目训练基于CNN的翻译模型,使用THEANO_FLAGS='floatX=float32,device=gpu2,lib.cnmem=1' python run_nnet.py -w data/exp1/,运行时报错,打印"The image and the kernel must have the same type. inputs(float64), kerns(float32)"的错误,然后使用THEANO_FLAGS='floatX=float64,device=gpu2,lib.cnmem=1' python run_nnet.py -w data/exp1/,运行成功。但几百个训练数据却需要十几分钟,运行十分缓慢。

使用nvidia-smi -l查看GPU情况,发现GPU memory usage 是满了,而GPU-Util却是0,top命令看CPU却是1600%(16核CPU),这与跑其他任务很不相同(GPU-Util接近100%,CPU不到100%)。看起来是CPU被打满了,而GPU空着,运算完全在CPU上进行。查找原因,Google这个问题,却没有找到什么满足需求的解答,只好回过头来阅读官方文档。

首先使用assert_no_cpu_op=raise:

THEANO_FLAGS="floatX=float64,device=gpu2,force_device=True,mode=FAST_RUN,lib.cnmem=1,assert_no_cpu_op=raise" python run_nnet.py

按照官方文档,如果设置了这个参数,有在CPU上执行的操作,是应该抛异常的。然而实际情况并没有。

仔细阅读官方文档,发现在theano的FAQ文档(refer: http://deeplearning.net/software/theano/faq.html)中说:

“It should be noted that using float32 and int{32, 64} together inside a function would provide float64 as output.

Since the GPU can’t compute this kind of output, it would be preferable not to use those dtypes together.

To help you find where float64 are created, see the warn_float64 Theano flag.”

也就是float64的话,GPU是不能计算的,所以就是CPU计算。进一步的,在使用GPU的文档中(refer: http://deeplearning.net/software/theano/tutorial/using_gpu.html):

"

  • Only computations with float32 data-type can be accelerated. Better support for float64 is expected in upcoming hardware but float64 computations are still relatively slow (Jan 2010).
  • Prefer constructors like matrixvector and scalar to dmatrixdvector and dscalar because the former will give you float32 variables when floatX=float32.
  • Ensure that your output variables have a float32 dtype and not float64. The more float32 variables are in your graph, the more work the GPU can do for you."

所以原因就是代码中有float64的输入。根据文档中建议,可以使用config的warn_float64来帮助寻找float64的输入,所以执行:

THEANO_FLAGS="floatX=float64,device=gpu2,force_device=True,mode=FAST_RUN,lib.cnmem=1,warn_float64=raise" python run_nnet.py -w data/exp1/

异常栈如下:

Traceback (most recent call last):
File "run_nnet.py", line 570, in <module>
main()
File "run_nnet.py", line 208, in main
nnet_q.set_input((x_q, x_q_overlap))
File ".../nn_layers.py", line 65, in set_input
self.output = self.output_func(input)
File ".../nn_layers.py", line 89, in output_func
layer.set_input(cur_input)

这个栈信息之反映了在网络set_input的时候有float64,但是float64的变量可是在此之前早就创建好的,所以还是无法定位到问题,这是一个然并卵的参数。

由于代码中的输入几乎都是由numpy生成或者load的,查阅numpy的文档,发现numpy建立数组的操作,如果没有指定dtype,那么默认就是float64,例如numpy.ones, numpy.zero, numpy.random.RandomState.randn等,theano的config(refer: http://deeplearning.net/software/theano/library/config.html)中有一个cast_policy参数,按照文档的说法,当设定floatX=float32,同时设置cast_policy=numpy+floatX时,执行过程中会自动的把numpy产生的数组转换成float32的。于是执行:

THEANO_FLAGS="floatX=float32,device=gpu2,force_device=True,mode=FAST_RUN,lib.cnmem=1,cast_policy=numpy+floatX" python run_nnet.py -w data/exp1/

结果。。。依然报错:"NotImplementedError: The image and the kernel must have the same type.inputs(float64), kerns(float32)"

这个参数的说明:

" Note that ‘numpy+floatX’ is not currently behaving exactly as planned (it is a work-in-progress), and thus you should consider it as experimental. "

好吧,果然还是实验性质的,有些情况搞不定。

那么最后一招,仔细的检查所有numpy的调用,把所有创建数组的地方都显示的指定dtype=numpy.float32,全部改好后,执行:

THEANO_FLAGS="floatX=float32,device=gpu2,force_device=True,mode=FAST_RUN,lib.cnmem=1" python run_nnet.py -w data/exp1/

成功的把GPU-Util打满,CPU也降到了100%,训练几百条数据的时间一下降到秒杀!

经验总结:

遇到问题阅读官方文档是十分有效的方法,往往常见问题在这些文档中已经说得很明确了,可以帮你明确的了解问题所在,进而找到解决方案。

GPU Memory Usage占满而GPU-Util却为0的调试的更多相关文章

  1. Reducing and Profiling GPU Memory Usage in Keras with TensorFlow Backend

    keras 自适应分配显存 & 清理不用的变量释放 GPU 显存 Intro Are you running out of GPU memory when using keras or ten ...

  2. Tensorflow默认占满全部GPU的全部资源

    一台服务器上装了多块GPU,默认情况下启动一个深度学习训练任务时,这个任务会占满每一块GPU的几乎全部存储空间.这就导致一个服务器基本上只能执行一个任务,而实际上任务可能并不需要如此多的资源,这相当于 ...

  3. Allowing GPU memory growth

    By default, TensorFlow maps nearly all of the GPU memory of all GPUs (subject to CUDA_VISIBLE_DEVICE ...

  4. tensorflow 运行效率 GPU memory leak 问题解决

    问题描述: Tensorflow 训练时运行越来越慢,重启后又变好. 用的是Tensorflow-GPU 1.2版本,在GPU上跑,大概就是才开始训练的时候每个batch的时间很低,然后随着训练的推进 ...

  5. 重置GPU显存 Reset GPU memory after CUDA errors

    Sometimes CUDA program crashed during execution, before memory was flushed. As a result, device memo ...

  6. 【JVM】jdk1.8-jetty-swap被占满问题排查

    背景 线上服务收到报警,报警内容:虚拟机swap区占用比例超过80%,如图: 本文着重描述排查问题的过程,在这个过程中不断的猜测–>验证–>推翻–>再猜测–>再验证–>再 ...

  7. 【Android 应用开发】Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题

    . 参考界面 : 携程app首页的广告栏, 使用ViewPager实现        自制页面效果图 : 源码下载地址: http://download.csdn.net/detail/han1202 ...

  8. Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题

    . 参考界面 : 携程app首页的广告栏, 使用ViewPager实现        自制页面效果图 : 源码下载地址: http://download.csdn.net/detail/han1202 ...

  9. 一个服务io占满,服务器无响应

    (1).服务器io占满,服务无响应, sar -q -f  /var/log/sa/sa28 上图显示plist-sz 增加了一倍 plist-sz 说明:进程列表中的进程(processes)和线程 ...

随机推荐

  1. PAT 1088 Rational Arithmetic[模拟分数的加减乘除][难]

    1088 Rational Arithmetic(20 分) For two rational numbers, your task is to implement the basic arithme ...

  2. linux系统进入单用户模式

    进入单用户模式可进行root账户和其他普通账户的密码的修改 1)Ubuntu 开机到grub时(在开机时长按shift键),用上下键移到第二行的恢复模式(recovery mode),按e(注意不是回 ...

  3. 关于c语言struct和typedef

    C++中使用: struct test{    int x, y;};就可以定义一个名为 test的结构体,但C中很可能编译通不过.C语言并不支持在struct后使用标示符定义结构体的名字,test将 ...

  4. BUG克星:几款优秀的BUG跟踪管理软件

    Bug管理是指对开发,测试,设计等过程中一系列活动过程中出现的bug问题给予纪录.审查.跟踪.分配.修改.验证.关闭.整理.分析.汇总以及删除等一系列活动状态的管理.,最后出相应图表统计,email通 ...

  5. IDEA,与gradle引入jar包报错

    Warning:<i><b>root project 'netty_lecture': Unable to resolve additional project configu ...

  6. 构建一个简单的Linux系统 MenuOs —— start_kernel到init进程(20135304刘世鹏)

    构建一个简单的Linux系统 MenuOs —— start_kernel到init进程 作者:刘世鹏20135304 <Linux内核分析>MOOC课程http://mooc.study ...

  7. 20145325张梓靖 《Java程序设计》第8周学习总结

    20145325张梓靖 <Java程序设计>第8周学习总结 教材学习内容总结 Logger java.util.logging包提供了日志功能相关类与接口,使用日志的起点是logger类, ...

  8. 学习Zookeeper之第2章Zookeeper安装

    第 2 章 Zookeeper安装 2.1 本地模式安装部署 2.2 配置参数解读 第 2 章 Zookeeper安装 2.1 本地模式安装部署 1)安装前准备: (1)安装 jdk (2)通过 fi ...

  9. nginx限制蜘蛛的频繁抓取

    蜘蛛抓取量骤增,导致服务器负载很高.最终用nginx的ngx_http_limit_req_module模块限制了百度蜘蛛的抓取频率.每分钟允许百度蜘蛛抓取200次,多余的抓取请求返回503. ngi ...

  10. Vue.js 2.x中事件总线(EvevntBus)及element-ui中全屏loading的使用

    事件总线(Event Bus)可以在vue项目的index.js文件中创建,也可以在一个独立的.vue文件中创建.使用时,在各个子组件中引入该组件即可. 项目中的全屏loading较多时,可以在根组件 ...