GPU显存占用浮动很大


#1

您好,
我在训练时,比如使用MSRA开源的Deformable ConvsNet(https://github.com/msracver/Deformable-ConvNets)的代码,会发现显存占用变动非常大,时而能占6G时而能占10G+。而我们的GPU是多个人一同使用,当某个人的显存忽上忽下时,另一个人突然跑一个实验占用了显存,刚才的训练的程序就会OOM而停掉,这样的显存变化对多人公用GPU的情况非常不友好,请问可以有什么办法改变这种情况吗?
注:这种情况是在mxnet 0.11.0(包含)之后的版本才出现的,在此之前的所有版本GPU显存使用上都非常稳定。


mxnet显存
#2

@mli @astonzhang 希望能得到大佬们的回复,这个问题对于mxnet/gluon的使用体验确实影响很大。


#3

用相同的模型,0.11.0之前没有这个现象吗?


#4

是的。MSRACVer的Deformable ConvsNet是一套很好的基于mxnet的检测框架,你们可以也试一下,确实会有显存占用很大且浮动厉害的现象。
在mxnet 0.11.0之前,可能占用4G显存,在0.11.0之后,就会占6~10G显存,且浮动很大。


#5

我在MSRACVer的FCIS下提过这个问题,MSRA的回答如下:


我个人感觉稳定的显存占用还是很重要的,所以希望能得到解决。


#6

你好,我问下你Deformable Convolution 配置的环境是什么呢 能详细说下吗?

我是的环境是:
GTX1080ti 对应 375的驱动
CUDA8.0 对应也是375版本号
CUDNN5.1

mxnet_cu80=0.12.0b20171021 pip 安装
mxnet =0.10 源码编译安装

安装好后 : mxnet-demo mnist gpu可以跑
DCN 的 deeplab demo 可以跑
但是rfcn的demo 跑不了 ,报错:


估计应该还是版本兼容问题 , 感谢解答疑惑


#7

我的batch_size设大了之后也浮动


#8

我找到了一个比较折中的办法,希望能给大家帮助:

在bash运行脚本增加:

export MXNET_GPU_MEM_POOL_RESERVE = 95

方法原理:

在mxnet源码中,以上修改的环境变量默认值是5,其官方解释为:

MXNET_GPU_MEM_POOL_RESERVE

Values: Int (default=5)
The percentage of GPU memory to reserve for things other than the GPU array, such as kernel launch or cudnn handle space.
If you see a strange out-of-memory error from the kernel launch, after multiple iterations, try setting this to a larger value.

而涉及该变量的源码在${MXNET_ROOT}/src/storage/pooled_storage_manager.h。其中相关代码为:


void GPUPooledStorageManager::Alloc(Storage::Handle* handle) {
std::lock_guard<std::mutex> lock(Storage::Get()->GetMutex(Context::kGPU));
size_t size = handle->size + NDEV;
auto&& reuse_it = memory_pool_.find(size);
if (reuse_it == memory_pool_.end() || reuse_it->second.size() == 0) {
size_t free, total;
cudaMemGetInfo(&free, &total);


if (free <= total * reserve_ / 100 || size > free - total * reserve_ / 100)
ReleaseAll();


void* ret = nullptr;
cudaError_t e = cudaMalloc(&ret, size);
if (e != cudaSuccess && e != cudaErrorCudartUnloading) {
LOG(FATAL) << "cudaMalloc failed: " << cudaGetErrorString(e);
}
used_memory_ += size;
handle->dptr = ret;
} else {
auto&& reuse_pool = reuse_it->second;
auto ret = reuse_pool.back();
reuse_pool.pop_back();
handle->dptr = ret;
}
}

reserve_ 的值为我们上面设置的环境变量。该方法的目的就是让上面加粗斜体的 if 语句代码在多数情况下为True,这样可以保证系统会一直清理多占用的显存,从而极大节省对显存的占用。
通过实验表明,该方法可以一定程度上缓解超大幅度的显存浮动,如果你的显存浮动在这么设置后还是很大,可以把这个参数设置为99。
:slightly_smiling_face:


#9

mxnet gluon GPU 显存波动太明显了, 比如同样的数据集, 同样的模型结构, 同样的 criterion,
mxnet gluon 可以从最开始的 500 MB 蹭蹭蹭涨到 3GB, 然后跌回500MB 如此往复.

隔壁 Pytorch 相同情况下 GPU 显存一直就是 500MB 左右, 而且隔壁的计算速度要快.

另外, 不论 batch_size 如何变, 只要没撑爆显存, gluon就会先涨到 3GB, 然后跌, 如此往复.
但如此同样条件下 隔壁 pytorch 还是会快那么一点.


#10

你设置成这个参数还会有同样的问题吗?


#11

非常感谢, 设置之后就好了


#12

这个怎么改的啊,是直接bash export。。。。。就可以了吗


#13

是的,直接export进去即可。


#14

你好,我设置好了,这个参数(已经99了)后可是模型一开始训练,显存就突然升高,然后就报cudaMalloc failed:out of memory 的错误,我想问下,通常怎么降低显存使用率的?