如果没有另行通知,TF 将在每个可见 GPU 上分配所有可用内存。以下是仅使用一个(或几个)GPU 的 5 种方法。
重击解决方案。CUDA_VISIBLE_DEVICES=0,1
在启动 python 或 jupyter notebook 之前在终端/控制台中设置:
CUDA_VISIBLE_DEVICES=0,1 python script.py
Python 解决方案。在构建会话之前运行接下来的 2 行代码
import os
os.environ["CUDA_VISIBLE_DEVICES"]="0,1"
自动化解决方案。下面的方法会自动检测其他脚本未使用的 GPU 设备并为您设置 CUDA_VISIBLE_DEVICES。您必须mask_unused_gpus
在构建会话之前调用。它将根据当前内存使用情况过滤掉 GPU。这样,您可以一次运行多个脚本实例,而无需更改代码或设置控制台参数。
功能:
import subprocess as sp
import os
def mask_unused_gpus(leave_unmasked=1):
ACCEPTABLE_AVAILABLE_MEMORY = 1024
COMMAND = "nvidia-smi --query-gpu=memory.free --format=csv"
try:
_output_to_list = lambda x: x.decode('ascii').split('\n')[:-1]
memory_free_info = _output_to_list(sp.check_output(COMMAND.split()))[1:]
memory_free_values = [int(x.split()[0]) for i, x in enumerate(memory_free_info)]
available_gpus = [i for i, x in enumerate(memory_free_values) if x > ACCEPTABLE_AVAILABLE_MEMORY]
if len(available_gpus) < leave_unmasked: raise ValueError('Found only %d usable GPUs in the system' % len(available_gpus))
os.environ["CUDA_VISIBLE_DEVICES"] = ','.join(map(str, available_gpus[:leave_unmasked]))
except Exception as e:
print('"nvidia-smi" is probably not installed. GPUs are not masked', e)
mask_unused_gpus(2)
限制:如果一次启动多个脚本可能会导致冲突,因为在构建会话时不会立即分配内存。如果这对您有问题,您可以使用原始源代码中的随机版本:mask_busy_gpus()
Tensorflow 2.0提出了另一种方法:
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
# Restrict TensorFlow to only use the first GPU
try:
tf.config.experimental.set_visible_devices(gpus[0], 'GPU')
except RuntimeError as e:
# Visible devices must be set at program startup
print(e)
Tensorflow/Keras还允许指定要与会话配置一起使用的 gpu。只有当设置环境变量不是一个选项(即 MPI 运行)时,我才能推荐它。因为它往往是所有方法中最不可靠的,尤其是对于 keras。
config = tf.ConfigProto()
config.gpu_options.visible_device_list = "0,1"
with tf.Session(config) as sess:
#or K.set_session(tf.Session(config))