disable diffusion解决3G显存报错

918次阅读
没有评论

今天在训练的时候突然报 oom 错误,看报错,显存分明够用,为什么会出现 oom 错误呢?
在报错里面提到

If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.
See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF
从报错可以看到是和 max_split_size_mb 这个参数有关系,从字面上看应该是可以设置的最大分割的大小,来避免内存碎片带来的 oom 问题。我理解来就是在分配显存的时候,可能是由于可分配显存的碎片设置的太小,无法分割导致的显存不足的问题?试着将这个值修改到 3.95GB 以上,(设置为 4000mb),仍然出现 OOM 的问题。

import os
os.environ[“PYTORCH_CUDA_ALLOC_CONF”] = “max_split_size_mb:4000”
难道不是是这个值越大越可以分配显存吗 =.=?还是说值越小,越利于显存分配?

带着疑问去网上搜了一番,找到了这个博客,里面是这样解释的。pytoch 的显存管理中,分配显存请求必须是连续的,max_split_size_mb 设置的是可分割最大的空闲 block,小于该值的空闲 block 可能由于被分割而无法连续使用,大于该值的空闲 block 将不会被分割。比如 max_split_size_mb 设置为 4000 时,所有小于 4000MB 空闲 block 都可能被分割开,当需要连续 4g 的空间时,就不存在可分配的 4g 的连续空闲 block,而报 OOM 错误。

max_split_size_mb 分割的对象是空闲 Block(这里有个暗含的前提:pytorch 显存管理机制中,显存请求必须是连续的)。
这里实际的逻辑是:由于默认策略是所有大小的空闲 Block 都可以被分割,所以导致 OOM 的显存请求发生时,
所有大于该请求的空闲 Block 有可能都已经被分割掉了。而将 max_split_size_mb 设置为小于该显存请求的值,
会阻止大于该请求的空闲 Block 被分割。如果显存总量确实充足,即可保证大于该请求的空闲 Block 总是存在,
从而避免了分配失败的发生。

最优设置策略:将 max_split_size_mb 设置为小于 OOM 发生时的显存请求大小最小值的最大整数值,就可以在保证跑大图的可行性的同时最大限度照顾性能。这里请求是 3.95GB 所以可以设置为 3950MB。

所以对于显存碎片化引起的 CUDA OOM,解决方法是将 PYTORCH_CUDA_ALLOC_CONF 的 max_split_size_mb 设为较小值。

set PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:3950
import os
os.environ[“PYTORCH_CUDA_ALLOC_CONF”] = “max_split_size_mb:3950”

正文完
 0
评论(没有评论)
验证码