小白最近在将以往tensorflow上的代码迁移到pytorch上来,结果在大致相同的参数,固定的有限显存的情况下,在tf上能够实现更大batchsize,而在pytorch上极其容易爆掉显存。请问这种情况是因为tensorflow这种静态图网路更容易节省显存嘛?


tensorflow是否比pytorch在显存管理利用方面更有优势

最近在将以往tensorflow上的代码迁移到pytorch上来,结果在大致相同的参数,固定的有限显存的情况下,在tf上能够实现更大batchsize,而在pytorch上极其容易爆掉显存。请问这种情况是因为tensorflow这种静态图网路更容易节省显存嘛?

不知道,取决于你具体干了啥......

关于第一个问题随便说两句吧. 对于tensorflow这样的一个declare-and-run的framework,能够事先完整的知道你要进行的计算,那在内存管理和优化方面, 理论上是有明显优势的.

实际中,举个最简单的例子: 什么时候释放内存?

TensorFlow(graph mode): tensor不再被后面的计算用到的时候释放.

Pytorch: tensor不可能再被后面的计算用到(也即无法从python里访问到,引用计数为0)的时候释放.

这两句话的微妙区别就是 pytorch无法准确判断一个tensor会不会再被用到, 所以只能保守释放. 并且经常要把管理内存的重任交给写代码的人, 用户要是不注意也容易写出内存不经济的代码.

除了释放tensor这一点之外, 在其他的operator fusion, in-place, gradient checkpointing等节约内存的手段上, 能够事先拿到computation graph都是一个巨大的优势.

当然, 作为用户, 用户总是知道完整的计算的. 所以即使在pytorch里,如果能够不怕麻烦的针对你要做的事情写一些奇怪的代码,内存利用效率不会有很本质的区别.


知道静态图确实可以优化内存,但是实际上动态图的自动内存管理也有很多优化的方法,并不是一定会爆的。

比如,静态图优化中的 Common Sub-expression Elimination 在动态图中可以通过 Function Memorization 来实现。 Automatic Differentiation 中需要用到之前结果的时候也可以通过实现 Binomial Checkpointing 来自动 Evict 之前的 Tensor 占用的内存。

只是上面提到的大家还没来得及实现而已……慢慢写……不著急……


TF 2.0 eager 模式和 PyTorch 比不好说,但 1.x 的 graph 模式和 PyTorch 比还是有优势的。

类比一下就是编译型语言和解释型语言的区别,编译器能拿到全局信息,能做的优化显然比只有局部信息的解释器要多。如果就内存占用来讲,即使是做了 JIT 编译的解释器,优化空间也显然不如编译器来得大。

当然优化潜力是一回事,有没有做到是另一回事了,这个也看具体的模型和框架版本,但设计原则大体能体现未来一段时间内的状况。


显存占用应该是差不多的,tensor中主要是数据占空间,所以只要数据一样,显存占用也不会差太多。

你应该是没有注意及时释放中间变数的引用。pytorch里tensor的生命周期就是python对象的生命周期,如果对象没被释放,就会一直占著显存。


为什么我刚好和你相反?我在tf2.0上运行不了的数据集,移到pytorch上就能运行。


别纠结了,pytorch吧,人这一生就那么几十年


推荐阅读:
相关文章