记困扰很久的pytorch加载模型OOM,python import执行流程,python“懒运行”,whindows控制ubuntu远程桌面

前言

半路接手项目,阅读代码,解决bug,优化速度。

part one

  1. 1050 Ti加载模型时OOM
    model.load_state_dict(torch.load(path))

Copies parameters and buffers from :attr:state_dict into
this module and its descendants. If :attr:strict is True, then
the keys of :attr:state_dict must exactly match the keys returned
by this module’s :meth:~torch.nn.Module.state_dict function.
Arguments:
state_dict (dict): a dict containing parameters and
persistent buffers.
strict (bool, optional): whether to strictly enforce that the keys
in :attr:state_dict match the keys returned by this module’s
:meth:~torch.nn.Module.state_dict function. Default: True
2019/1/16补:
其实问题是出在main函数,当时一直没考虑到(因为Java中必须得主函数作为运行入口,Python不强求,所以写Python代码没养成好习惯)。
所以,尽量写主函数,尽量少进行耗内存的初始化,确实需要该初始化操作的话,控制好它的初始化时间、范围。无用的import 尽量不要。

  1. 继续debug,发现在某个py脚本中,有变量赋值
    sess, saver, net = load_tf_model()
    所以在import的时候,这句代码会被解释执行,load_tf_model()函数中,
    net = get_network("VGGnet_test")执行了模型加载操作,这里耗掉3253MB。
    注意到tensorflow创建了2个gpu task,第一个耗掉3253MB:
    Creating TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 3253 MB memory)
    然后第二个Task:
    Creating TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 29 MB memory)

以上都发生在import模块时。

关于Python import

以前光是知道Python解释执行,一行行解释执行;Java编译运行,编译完到处运行。
但是没注意到Python import导入模块执行流程
在python中使用import语句导入模块时,python通过三个步骤来完成这个行为。
1:在python模块加载路径中查找相应的模块文件
2:将模块文件编译成中间代码
3:执行模块文件中的代码

在python中模块的导入动作只发生一次。也就是说当一个模块在一个文件中被导入过一次以后,当另外的文件继续需要导入这个模块时,python首先会在sys.modules这个变量中查出是否已经导入过这个模块,如果已经导入过则上面三个步骤不会执行,直接引用之前导入的内存中的内容。
在步骤2中,python首先会查找对应模块的.pyc文件,看该文件的最后修改时间是否比对应的.py文件的走后修改时间早,如果遭遇.py文件的最后修改时间,则重新编译模块并重新生成字节码文件。注意,一个python程序的顶层文件不会生成.pyc文件。
当python完成步骤2以后会执行python文件中的语句,以生成对应的对象属性,比如def语句生成该模块的一个函数属性等。因为这个特性,假如模块中有一个print语句 , 那么, 当该模块被第一次加载的时候,该输出语句就会将内容输出,但是由于模块只能被import一次,所以,当模块第二次被加载的时候,上面这三个步骤都不会被执行,那么,这个输出不会再次出现。
CSDN: tuxl_c_s_d_n_python import导入模块执行流程分析

举个例子:

a.py

a = 3
print(3)

b.py:

import a

也就是说,b除了导入a,什么都不做。但是执行 b.py,是会打印出3的。
再举个例子:
将a.py改为:

a = 3

def c():
    print(a)

而b脚本不变,执行,不会打印。
所以,平常写python代码时,如果想提升速度或者节约内存,能在方法里赋值的变量尽量少写在全局,
关查那些官方代码,你也会发现这个问题。

以上内容,让熟悉python的人见笑了,哈哈。Java是不会这样的,因为就一个main函数,除非并发编程或者static啥的,不会出现这样的“提前”计算的情况。这样一想,spar等一些框架的laze 操作,真的不错。

part two

import结束,进入main执行代码时:
rois = sess.run([net.get_output('rois')[0]], feed_dict=feed_dict)
再次分配GPU,
ran out of memory trying to allocate 3.39GiB. The caller indicates that this is not a failure, but...

疑问:
gpu不够分配,是不是自动全部转入cpu计算?

应该是的,我安装的是gpu版本的框架,当不强制设置使用GPU时,只是warning显存不够分配,提示几次后,代码正常执行,但是强制设置为gpu运行时,代码报错。所以我猜测:gpu不够分配,是不是自动全部转入cpu计算。

part three

上面的几次GPU 信息,应该是分配GPU,并没有使用吧?
先放着了,借朋友1080 Ti用一用。
关于cuda 、cudnn、tensorflow的版本匹配:

TensorFlow 1.7 may be the last time we support Cuda versions below 8.0.
Starting with TensorFlow 1.8 release, 8.0 will be the minimum supported
version.
TensorFlow 1.7 may be the last time we support cuDNN versions below 6.0.
Starting with TensorFlow 1.8 release, 6.0 will be the minimum supported
version.


但是1.6.0以及1.5.0的发布:

Prebuilt binaries are now built against CUDA 9.0 and cuDNN 7.
Prebuilt binaries will use AVX instructions. This may break TF on older CPUs.

保险起见,还是tensorflow-gpu==1.4.1。2017年12月9日发布的。
使用清华镜像,选择版本方便:
记困扰很久的pytorch加载模型OOM,python import执行流程,python“懒运行”,whindows控制ubuntu远程桌面_第1张图片

pip install \ -i https://pypi.tuna.tsinghua.edu.cn/simple/ \ https://mirrors.tuna.tsinghua.edu.cn/tensorflow/linux/gpu/tensorflow_gpu-1.4.1-cp36-cp36m-linux_x86_64.whl

注意:1.4.1没有Windows的二进制文件。1.4.1只是修复了CloudML Engine,CloudML Engine仅支持Linux,Windows不受影响。

报错

  1. 提示缺少库:ImportError: libcublas.so
    检查你的配置文件~/.bashrc中配置的cuda的lib是否正确,也就是说,你安装cuda时,是不是改了文件名。
  2. command not found: shopt
    如果你在用zsh:(其实个人感觉,fish更好用)
    将所需配置修改写入~/.zshrc
    执行 source ~/.zshrc

whindows控制ubuntu远程桌面

不使用teamviewer,
参考:
VNC实现Windows远程访问Ubuntu 16.04(无需安装第三方桌面)
xrdp完美实现Windows远程访问Ubuntu 16.04

你可能感兴趣的:(Deep/Machine,Learning)