如何在张量流中获取当前可用的 GPU?
How to get current available GPUs in tensorflow?
我有使用分布式 TensorFlow 的计划,我看到 TensorFlow 可以使用 GPU 进行训练和测试。在集群环境中,每台机器可能有 0 个或 1 个或更多 GPU,我想 运行 我的 TensorFlow 图在尽可能多的机器上进入 GPU。
我发现当 运行ning tf.Session()
TensorFlow 在日志消息中提供有关 GPU 的信息,如下所示:
I tensorflow/core/common_runtime/gpu/gpu_init.cc:126] DMA: 0
I tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 0: Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:838] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 1080, pci bus id: 0000:01:00.0)
我的问题是如何从 TensorFlow 获取有关当前可用 GPU 的信息?我可以从日志中获取加载的 GPU 信息,但我想以更复杂的编程方式进行。
我也可以使用 CUDA_VISIBLE_DEVICES 环境变量有意限制 GPU,所以我不想知道从 OS 内核获取 GPU 信息的方法。
简而言之,如果机器中有两个可用的 GPU,我想要一个像 tf.get_available_gpus()
这样的函数,它将 return ['/gpu:0', '/gpu:1']
。我该如何实施?
有一个未记录的方法,称为 device_lib.list_local_devices()
that enables you to list the devices available in the local process. (N.B. As an undocumented method, this is subject to backwards incompatible changes.) The function returns a list of DeviceAttributes
protocol buffer 个对象。您可以提取 GPU 设备的字符串设备名称列表,如下所示:
from tensorflow.python.client import device_lib
def get_available_gpus():
local_device_protos = device_lib.list_local_devices()
return [x.name for x in local_device_protos if x.device_type == 'GPU']
请注意(至少到 TensorFlow 1.4),调用 device_lib.list_local_devices()
将 运行 一些初始化代码,默认情况下,这些代码将在所有设备上分配所有 GPU 内存(GitHub issue). To avoid this, first create a session with an explicitly small per_process_gpu_fraction
, or allow_growth=True
, to prevent all of the memory being allocated. See 了解更多详情。
您可以使用以下代码查看所有设备列表:
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
除了 Mrry 的出色解释,他建议使用 device_lib.list_local_devices()
我可以向您展示如何从命令行检查 GPU 相关信息。
因为目前只有 Nvidia 的 gpus 适用于 NN 框架,所以答案仅涵盖它们。 Nvidia has a page 他们在其中记录了如何使用 /proc 文件系统接口获取有关驱动程序、任何已安装的 NVIDIA 显卡和 AGP 状态的 运行 时间信息。
/proc/driver/nvidia/gpus/0..N/information
Provide information about
each of the installed NVIDIA graphics adapters (model name, IRQ, BIOS
version, Bus Type). Note that the BIOS version is only available while
X is running.
因此您可以 运行 从命令行 cat /proc/driver/nvidia/gpus/0/information
执行此操作并查看有关您的第一个 GPU 的信息。很容易run this from python,你也可以检查第二个,第三个,第四个GPU,直到它失败。
Mrry 的答案肯定更可靠,我不确定我的答案是否适用于非 linux 机器,但 Nvidia 的页面提供了其他有趣的信息,但没有多少人知道。
test util中还有一个方法。
所以所有需要做的是:
tf.test.is_gpu_available()
and/or
tf.test.gpu_device_name()
在 Tensorflow 文档中查找参数。
给出了 GPU 的数量,但它也分配了这些 GPU 上的所有内存。您可以通过在调用 device_lib.list_local_devices() 之前创建一个具有固定较低内存的会话来避免这种情况,这对于某些应用程序来说可能是不需要的。
我最终使用 nvidia-smi 来获取 GPU 的数量,而没有在它们上分配任何内存。
import subprocess
n = str(subprocess.check_output(["nvidia-smi", "-L"])).count('UUID')
从 TensorFlow 2.1 开始,您可以使用 tf.config.list_physical_devices('GPU')
:
import tensorflow as tf
gpus = tf.config.list_physical_devices('GPU')
for gpu in gpus:
print("Name:", gpu.name, " Type:", gpu.device_type)
如果您安装了两个 GPU,它会输出:
Name: /physical_device:GPU:0 Type: GPU
Name: /physical_device:GPU:1 Type: GPU
在 TF 2.0 中,您必须添加 experimental
:
gpus = tf.config.experimental.list_physical_devices('GPU')
参见:
以下在 tensorflow 2 中有效:
import tensorflow as tf
gpus = tf.config.experimental.list_physical_devices('GPU')
for gpu in gpus:
print("Name:", gpu.name, " Type:", gpu.device_type)
从 2.1 开始,您可以删除 experimental
:
gpus = tf.config.list_physical_devices('GPU')
https://www.tensorflow.org/api_docs/python/tf/config/list_physical_devices
使用这种方式并检查所有部分:
from __future__ import absolute_import, division, print_function, unicode_literals
import numpy as np
import tensorflow as tf
import tensorflow_hub as hub
import tensorflow_datasets as tfds
version = tf.__version__
executing_eagerly = tf.executing_eagerly()
hub_version = hub.__version__
available = tf.config.experimental.list_physical_devices("GPU")
print("Version: ", version)
print("Eager mode: ", executing_eagerly)
print("Hub Version: ", h_version)
print("GPU is", "available" if avai else "NOT AVAILABLE")
确保您的 GPU 支持机器上安装了最新的 TensorFlow 2.x GPU,
在python,
中执行以下代码
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
将得到如下输出,
2020-02-07 10:45:37.587838: I
tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1006] successful
NUMA node read from SysFS had negative value (-1), but there must be
at least one NUMA node, so returning NUMA node zero 2020-02-07
10:45:37.588896: I
tensorflow/core/common_runtime/gpu/gpu_device.cc:1746] Adding visible
gpu devices: 0, 1, 2, 3, 4, 5, 6, 7 Num GPUs Available: 8
我的机器上有一个名为 NVIDIA GTX GeForce 1650 Ti
的 GPU tensorflow-gpu==2.2.0
运行下面两行代码:
import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
输出:
Num GPUs Available: 1
我正在研究 TF-2.1 和 torch,所以我不想在任何 ML 框架中指定这个 automacit 选择。我只是用原来的 nvidia-smi 和 os.environ 得到一个空闲的 gpu。
def auto_gpu_selection(usage_max=0.01, mem_max=0.05):
"""Auto set CUDA_VISIBLE_DEVICES for gpu
:param mem_max: max percentage of GPU utility
:param usage_max: max percentage of GPU memory
:return:
"""
os.environ['CUDA_DEVICE_ORDER'] = 'PCI_BUS_ID'
log = str(subprocess.check_output("nvidia-smi", shell=True)).split(r"\n")[6:-1]
gpu = 0
# Maximum of GPUS, 8 is enough for most
for i in range(8):
idx = i*3 + 2
if idx > log.__len__()-1:
break
inf = log[idx].split("|")
if inf.__len__() < 3:
break
usage = int(inf[3].split("%")[0].strip())
mem_now = int(str(inf[2].split("/")[0]).strip()[:-3])
mem_all = int(str(inf[2].split("/")[1]).strip()[:-3])
# print("GPU-%d : Usage:[%d%%]" % (gpu, usage))
if usage < 100*usage_max and mem_now < mem_max*mem_all:
os.environ["CUDA_VISIBLE_EVICES"] = str(gpu)
print("\nAuto choosing vacant GPU-%d : Memory:[%dMiB/%dMiB] , GPU-Util:[%d%%]\n" %
(gpu, mem_now, mem_all, usage))
return
print("GPU-%d is busy: Memory:[%dMiB/%dMiB] , GPU-Util:[%d%%]" %
(gpu, mem_now, mem_all, usage))
gpu += 1
print("\nNo vacant GPU, use CPU instead\n")
os.environ["CUDA_VISIBLE_EVICES"] = "-1"
如果我可以获得任何 GPU,它会将 CUDA_VISIBLE_EVICES 设置为该 gpu 的 BUSID :
GPU-0 is busy: Memory:[5738MiB/11019MiB] , GPU-Util:[60%]
GPU-1 is busy: Memory:[9688MiB/11019MiB] , GPU-Util:[78%]
Auto choosing vacant GPU-2 : Memory:[1MiB/11019MiB] , GPU-Util:[0%]
否则,设置为 -1 以使用 CPU:
GPU-0 is busy: Memory:[8900MiB/11019MiB] , GPU-Util:[95%]
GPU-1 is busy: Memory:[4674MiB/11019MiB] , GPU-Util:[35%]
GPU-2 is busy: Memory:[9784MiB/11016MiB] , GPU-Util:[74%]
No vacant GPU, use CPU instead
注意:在之前使用此功能导入任何需要GPU的ML框架,然后它可以自动选择GPU。此外,您还可以轻松设置多个任务。
在 TensorFlow Core v2.3.0 中,以下代码应该可以工作。
import tensorflow as tf
visible_devices = tf.config.get_visible_devices()
for devices in visible_devices:
print(devices)
根据您的环境,此代码会产生流畅的结果。
PhysicalDevice(name='/physical_device:CPU:0', device_type='CPU')
PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')
tensorflow推荐的最新版本:
tf.config.list_physical_devices('GPU')
运行以下任意shell
python -c "import tensorflow as tf; print(\"Num GPUs Available: \", len(tf.config.list_physical_devices('GPU')))"
我有使用分布式 TensorFlow 的计划,我看到 TensorFlow 可以使用 GPU 进行训练和测试。在集群环境中,每台机器可能有 0 个或 1 个或更多 GPU,我想 运行 我的 TensorFlow 图在尽可能多的机器上进入 GPU。
我发现当 运行ning tf.Session()
TensorFlow 在日志消息中提供有关 GPU 的信息,如下所示:
I tensorflow/core/common_runtime/gpu/gpu_init.cc:126] DMA: 0
I tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 0: Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:838] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 1080, pci bus id: 0000:01:00.0)
我的问题是如何从 TensorFlow 获取有关当前可用 GPU 的信息?我可以从日志中获取加载的 GPU 信息,但我想以更复杂的编程方式进行。 我也可以使用 CUDA_VISIBLE_DEVICES 环境变量有意限制 GPU,所以我不想知道从 OS 内核获取 GPU 信息的方法。
简而言之,如果机器中有两个可用的 GPU,我想要一个像 tf.get_available_gpus()
这样的函数,它将 return ['/gpu:0', '/gpu:1']
。我该如何实施?
有一个未记录的方法,称为 device_lib.list_local_devices()
that enables you to list the devices available in the local process. (N.B. As an undocumented method, this is subject to backwards incompatible changes.) The function returns a list of DeviceAttributes
protocol buffer 个对象。您可以提取 GPU 设备的字符串设备名称列表,如下所示:
from tensorflow.python.client import device_lib
def get_available_gpus():
local_device_protos = device_lib.list_local_devices()
return [x.name for x in local_device_protos if x.device_type == 'GPU']
请注意(至少到 TensorFlow 1.4),调用 device_lib.list_local_devices()
将 运行 一些初始化代码,默认情况下,这些代码将在所有设备上分配所有 GPU 内存(GitHub issue). To avoid this, first create a session with an explicitly small per_process_gpu_fraction
, or allow_growth=True
, to prevent all of the memory being allocated. See
您可以使用以下代码查看所有设备列表:
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
除了 Mrry 的出色解释,他建议使用 device_lib.list_local_devices()
我可以向您展示如何从命令行检查 GPU 相关信息。
因为目前只有 Nvidia 的 gpus 适用于 NN 框架,所以答案仅涵盖它们。 Nvidia has a page 他们在其中记录了如何使用 /proc 文件系统接口获取有关驱动程序、任何已安装的 NVIDIA 显卡和 AGP 状态的 运行 时间信息。
/proc/driver/nvidia/gpus/0..N/information
Provide information about each of the installed NVIDIA graphics adapters (model name, IRQ, BIOS version, Bus Type). Note that the BIOS version is only available while X is running.
因此您可以 运行 从命令行 cat /proc/driver/nvidia/gpus/0/information
执行此操作并查看有关您的第一个 GPU 的信息。很容易run this from python,你也可以检查第二个,第三个,第四个GPU,直到它失败。
Mrry 的答案肯定更可靠,我不确定我的答案是否适用于非 linux 机器,但 Nvidia 的页面提供了其他有趣的信息,但没有多少人知道。
test util中还有一个方法。 所以所有需要做的是:
tf.test.is_gpu_available()
and/or
tf.test.gpu_device_name()
在 Tensorflow 文档中查找参数。
我最终使用 nvidia-smi 来获取 GPU 的数量,而没有在它们上分配任何内存。
import subprocess
n = str(subprocess.check_output(["nvidia-smi", "-L"])).count('UUID')
从 TensorFlow 2.1 开始,您可以使用 tf.config.list_physical_devices('GPU')
:
import tensorflow as tf
gpus = tf.config.list_physical_devices('GPU')
for gpu in gpus:
print("Name:", gpu.name, " Type:", gpu.device_type)
如果您安装了两个 GPU,它会输出:
Name: /physical_device:GPU:0 Type: GPU
Name: /physical_device:GPU:1 Type: GPU
在 TF 2.0 中,您必须添加 experimental
:
gpus = tf.config.experimental.list_physical_devices('GPU')
参见:
以下在 tensorflow 2 中有效:
import tensorflow as tf
gpus = tf.config.experimental.list_physical_devices('GPU')
for gpu in gpus:
print("Name:", gpu.name, " Type:", gpu.device_type)
从 2.1 开始,您可以删除 experimental
:
gpus = tf.config.list_physical_devices('GPU')
https://www.tensorflow.org/api_docs/python/tf/config/list_physical_devices
使用这种方式并检查所有部分:
from __future__ import absolute_import, division, print_function, unicode_literals
import numpy as np
import tensorflow as tf
import tensorflow_hub as hub
import tensorflow_datasets as tfds
version = tf.__version__
executing_eagerly = tf.executing_eagerly()
hub_version = hub.__version__
available = tf.config.experimental.list_physical_devices("GPU")
print("Version: ", version)
print("Eager mode: ", executing_eagerly)
print("Hub Version: ", h_version)
print("GPU is", "available" if avai else "NOT AVAILABLE")
确保您的 GPU 支持机器上安装了最新的 TensorFlow 2.x GPU, 在python,
中执行以下代码from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
将得到如下输出,
2020-02-07 10:45:37.587838: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1006] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero 2020-02-07 10:45:37.588896: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1746] Adding visible gpu devices: 0, 1, 2, 3, 4, 5, 6, 7 Num GPUs Available: 8
我的机器上有一个名为 NVIDIA GTX GeForce 1650 Ti
的 GPU tensorflow-gpu==2.2.0
运行下面两行代码:
import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
输出:
Num GPUs Available: 1
我正在研究 TF-2.1 和 torch,所以我不想在任何 ML 框架中指定这个 automacit 选择。我只是用原来的 nvidia-smi 和 os.environ 得到一个空闲的 gpu。
def auto_gpu_selection(usage_max=0.01, mem_max=0.05):
"""Auto set CUDA_VISIBLE_DEVICES for gpu
:param mem_max: max percentage of GPU utility
:param usage_max: max percentage of GPU memory
:return:
"""
os.environ['CUDA_DEVICE_ORDER'] = 'PCI_BUS_ID'
log = str(subprocess.check_output("nvidia-smi", shell=True)).split(r"\n")[6:-1]
gpu = 0
# Maximum of GPUS, 8 is enough for most
for i in range(8):
idx = i*3 + 2
if idx > log.__len__()-1:
break
inf = log[idx].split("|")
if inf.__len__() < 3:
break
usage = int(inf[3].split("%")[0].strip())
mem_now = int(str(inf[2].split("/")[0]).strip()[:-3])
mem_all = int(str(inf[2].split("/")[1]).strip()[:-3])
# print("GPU-%d : Usage:[%d%%]" % (gpu, usage))
if usage < 100*usage_max and mem_now < mem_max*mem_all:
os.environ["CUDA_VISIBLE_EVICES"] = str(gpu)
print("\nAuto choosing vacant GPU-%d : Memory:[%dMiB/%dMiB] , GPU-Util:[%d%%]\n" %
(gpu, mem_now, mem_all, usage))
return
print("GPU-%d is busy: Memory:[%dMiB/%dMiB] , GPU-Util:[%d%%]" %
(gpu, mem_now, mem_all, usage))
gpu += 1
print("\nNo vacant GPU, use CPU instead\n")
os.environ["CUDA_VISIBLE_EVICES"] = "-1"
如果我可以获得任何 GPU,它会将 CUDA_VISIBLE_EVICES 设置为该 gpu 的 BUSID :
GPU-0 is busy: Memory:[5738MiB/11019MiB] , GPU-Util:[60%]
GPU-1 is busy: Memory:[9688MiB/11019MiB] , GPU-Util:[78%]
Auto choosing vacant GPU-2 : Memory:[1MiB/11019MiB] , GPU-Util:[0%]
否则,设置为 -1 以使用 CPU:
GPU-0 is busy: Memory:[8900MiB/11019MiB] , GPU-Util:[95%]
GPU-1 is busy: Memory:[4674MiB/11019MiB] , GPU-Util:[35%]
GPU-2 is busy: Memory:[9784MiB/11016MiB] , GPU-Util:[74%]
No vacant GPU, use CPU instead
注意:在之前使用此功能导入任何需要GPU的ML框架,然后它可以自动选择GPU。此外,您还可以轻松设置多个任务。
在 TensorFlow Core v2.3.0 中,以下代码应该可以工作。
import tensorflow as tf
visible_devices = tf.config.get_visible_devices()
for devices in visible_devices:
print(devices)
根据您的环境,此代码会产生流畅的结果。
PhysicalDevice(name='/physical_device:CPU:0', device_type='CPU') PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')
tensorflow推荐的最新版本:
tf.config.list_physical_devices('GPU')
运行以下任意shell
python -c "import tensorflow as tf; print(\"Num GPUs Available: \", len(tf.config.list_physical_devices('GPU')))"