我在一个共享计算资源的环境中工作,也就是说,我们有一些服务器机器配备了几个Nvidia Titan X GPU。
对于小到中等大小的型号,12GB的Titan X通常足以让2-3人在同一GPU上同时进行训练。如果模型足够小以至于单个模型没有充分利用Titan X的所有计算单元,那么与在另一个之后运行一个训练过程相比,这实际上可以导致加速。即使在并发访问GPU确实减慢了单个培训时间的情况下,仍然可以灵活地让多个用户同时在GPU上运行。
TensorFlow的问题在于,默认情况下,它在启动时会在GPU上分配全部可用内存。即使对于一个小的2层神经网络,我也看到12 GB的Titan X已用完。
有没有办法让TensorFlow只分配4GB的GPU内存,如果有人知道这个数量对于给定的模型来说足够了?
您可以通过传递tf.Session
作为可选tf.GPUOptions
参数的一部分来设置构造config
时要分配的GPU内存的分数:
# Assume that you have 12GB of GPU memory and want to allocate ~4GB:
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))
per_process_gpu_memory_fraction
充当GPU内存量的硬上限,该内存将由同一台机器上的每个GPU上的进程使用。目前,该分数统一应用于同一台机器上的所有GPU;没有办法在每GPU的基础上设置它。
您可以使用
TF_FORCE_GPU_ALLOW_GROWTH=true
在你的环境变量中。
在tensorflow代码:
bool GPUBFCAllocator::GetAllowGrowthValue(const GPUOptions& gpu_options) {
const char* force_allow_growth_string =
std::getenv("TF_FORCE_GPU_ALLOW_GROWTH");
if (force_allow_growth_string == nullptr) {
return gpu_options.allow_growth();
}
config = tf.ConfigProto()
config.gpu_options.allow_growth=True
sess = tf.Session(config=config)
以下是本书Deep Learning with TensorFlow
的摘录
在某些情况下,希望该过程仅分配可用内存的子集,或者仅增加该过程所需的内存使用量。 TensorFlow在会话中提供了两个配置选项来控制它。第一个是
allow_growth
选项,它尝试仅基于运行时分配分配尽可能多的GPU内存,它开始分配非常少的内存,并且随着会话运行并需要更多GPU内存,我们扩展了所需的GPU内存区域TensorFlow流程。
1)允许增长:(更灵活)
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config, ...)
第二种方法是per_process_gpu_memory_fraction
选项,它确定应该分配each
可见GPU的总内存量的分数。注意:不需要释放内存,它甚至可以在完成后恶化内存碎片。
2)分配固定内存:
要仅通过以下方式分配每个GPU的总内存的40%
:
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.4
session = tf.Session(config=config, ...)
注意:仅当您真正想要绑定TensorFlow进程上可用的GPU内存量时,这才有用。
上面的所有答案都假设使用sess.run()
调用执行,这在最近版本的TensorFlow中成为例外而不是规则。
当使用tf.Estimator
框架(TensorFlow 1.4及更高版本)时,将分数传递给隐式创建的MonitoredTrainingSession
的方法是,
opts = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
conf = tf.ConfigProto(gpu_options=opts)
trainingConfig = tf.estimator.RunConfig(session_config=conf, ...)
tf.estimator.Estimator(model_fn=...,
config=trainingConfig)
同样在Eager模式(TensorFlow 1.5及以上版本)中,
opts = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
conf = tf.ConfigProto(gpu_options=opts)
tfe.enable_eager_execution(config=conf)
编辑:11-04-2018作为一个例子,如果你要使用tf.contrib.gan.train
,那么你可以使用类似于下面的东西:
tf.contrib.gan.gan_train(........, config=conf)
From the 2.0 Alpha docs, the answer is now just one line before you do anything with TensorFlow:
import tensorflow as tf
tf.config.gpu.set_per_process_memory_growth(True)
无耻插件:如果您安装支持GPU的Tensorflow,会话将首先分配所有GPU,无论您将其设置为仅使用CPU还是GPU。我可以添加我的提示,即使您将图表设置为仅使用CPU,您应该设置相同的配置(如上面的回答:))以防止不必要的GPU占用。
在像IPython这样的交互式界面中,您还应该设置configure,否则它将分配所有内存并且几乎不会为其他内存。有时很难注意到这一点。
我试图在voc数据集上训练unet,但由于图像大小庞大,内存完成。我尝试了所有上述提示,甚至尝试批量大小== 1,但没有改善。有时TensorFlow版本也会导致内存问题。尝试使用
pip install tensorflow-gpu == 1.8.0
我是张力流的新手,我有Geforce 740m或者带有2GB内存的GPU,我正在运行mnist手写的一种原生语言示例,其中包含38700个图像和4300个测试图像的训练数据,并试图获得精确度,回想一下, F1使用以下代码作为sklearn并没有给我精确的结果。一旦我将其添加到我现有的代码中,我开始收到GPU错误。
TP = tf.count_nonzero(predicted * actual)
TN = tf.count_nonzero((predicted - 1) * (actual - 1))
FP = tf.count_nonzero(predicted * (actual - 1))
FN = tf.count_nonzero((predicted - 1) * actual)
prec = TP / (TP + FP)
recall = TP / (TP + FN)
f1 = 2 * prec * recall / (prec + recall)
加上我的模型很重,我想,我在147,148个时期之后得到了内存错误,然后我想为什么不为任务创建函数所以我不知道它是否在tensrorflow中这样工作,但我想如果局部变量是使用时,当超出范围时,它可能释放内存,我定义了上述元素进行模块训练和测试,我能够实现10000个时代而没有任何问题,我希望这会有所帮助..
API又改变了。它现在可以在:
tf.config.experimental.set_memory_growth(
device,
enable
)
别名:
https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/config/experimental/set_memory_growth https://www.tensorflow.org/beta/guide/using_gpu#limiting_gpu_memory_growth