train正常,evaluation的时候GPU爆炸???代码工整的谎言

快半个月前遇到的问题了,还是记录一下

问题描述

在用LG训练的时候,train_batch_size=8,eval_batch_size=4。按道理这种情况下GPU占用峰值停留在train, 而eval的时候应该很低才对,因为没有计算图的accumulate,GPU上只包括model和data。
但是问题就是出现的那么惊悚,我在训练的时候老是炸显存,而且每次炸的时候都是在eval.后来继续调小train和eval的batch_size,居然发现eval的时候显存占用居然是train的2倍左右,而test的时候则是3、4倍.

put everything in a function!!!

原来是因为自己的代码写的所谓的”太规整了”,我充分地运用面向对象思维,将一个model封装一层又一层,因为考虑到eval和train都需要forward model,所以把forward和compute loss等,那些共同的部分全部抽象出来,到一个父类里面,结果就和上面说的那样,still return loss,也就是计算loss的那个fuc return出来,一层层返回到最外层,然后return了好几层之后才loss.backward()

而出现这个问题的原因就和python本身的生态有关系了,因为python的每个function会保留里面的variable.所以要是把loss写在另一个function里面,通过return调用返回,而trian和eval都是共用一块代码的,那么eval的时候,train留下的reference还会保留,而eval的时候no_grad会失效,不管你包几层都没用,因为你计算loss,to.device()等和GPU有关的操作不在一片代码块。

所以说,这塔玛不是吃力不讨好,一顿操作秀翻自己br>

train正常,evaluation的时候GPU爆炸???代码工整的谎言
这还是我后面改过的,最原始的版本那真的是啊!注释写的比代码多,你敢信/p>

感悟:

要问,这些工程化的编码习惯好不好呢/strong>
答案是,当然好了,应该说是非常好! 本科阶段就养成那么好的编码习惯以后进工业可以少吃很多无知亏。

但是——没必要,我说的没必要是指现在没必要大花心思取保证自己的代码工程化程度,因为说实在的,在整个project代码量本来就称不上一个工程的时候,费尽心思,吹毛求疵地用工程化思想框住自己的代码,那就是个错误,或者说纯属吃饱了撑。

SE这个课程本身传授的就不是啥算法啊,啥很具体技术,它传授的是前人的经验,是血泪,是前人在面对巨大代码量软件开发过程中,因为缺乏工程化思想严格把控,而流下的血泪!是几十个、几百个人的大团队,在真刀真枪开发软件的时候才能派的上用场的!

我这么个半吊子三脚猫的丹童,就跑点experiment,先不说代码量算不算的上一个工程(虽然我觉得我这个exp 用python写了上千行了,应该快算得上了),关键是这代码本来就不是用在工程上的。就好比,在练习九阳神功的时候,挥刀自宫了。这拟码真没必要啊…

参考:

  • Increase the CUDA memory twice then stop increasing
  • Model.eval() get more and more gpu memory #4932

文章知识点与官方知识档案匹配,可进一步学习相关知识Python入门技能树人工智能深度学习210014 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年1月23日
下一篇 2021年1月23日

相关推荐