TensorFlow默认使用机器上的所有可用GPU吗?

17

我机器上装有3张GTX Titan显卡。我用提供的cifar10_train.py运行Cifar10的示例,并得到如下输出:

I tensorflow/core/common_runtime/gpu/gpu_init.cc:60] cannot enable peer access from device ordinal 0 to device ordinal 1
I tensorflow/core/common_runtime/gpu/gpu_init.cc:60] cannot enable peer access from device ordinal 1 to device ordinal 0
I tensorflow/core/common_runtime/gpu/gpu_init.cc:127] DMA: 0 1 
I tensorflow/core/common_runtime/gpu/gpu_init.cc:137] 0:   Y N 
I tensorflow/core/common_runtime/gpu/gpu_init.cc:137] 1:   N Y 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:694] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX TITAN, pci bus id: 0000:03:00.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:694] Creating TensorFlow device (/gpu:1) -> (device: 1, name: GeForce GTX TITAN, pci bus id: 0000:84:00.0)

在我看来,TensorFlow正在尝试在两个设备上(gpu0和gpu1)初始化自己。

我的问题是为什么它只在两个设备上执行此操作,是否有任何方法可以防止这种情况?(我只希望它像单个GPU一样运行)


这确实很有帮助。但是为什么TensorFlow会自动初始化机器上的所有设备呢?顺便说一下,只要给出一个答案我就会接受。 - Zk1001
TensorFlow的目标是“从研究到生产”。它似乎默认使用所有计算能力以尽快完成工作,这符合预期。实际上,这是可以调整的。但是你提到了3个GPU,而日志中只显示了2个。为什么呢? - Eric Platon
我刚刚发现是因为第三个GPU没有运行(原因我还不知道),所以我猜如果它能正常工作,TensorFlow也会使用它。 - Zk1001
1个回答

23

参见:使用GPU

手动设备放置

如果您想让特定操作在您选择的设备上运行而不是自动选择的设备,可以使用tf.device创建设备上下文,并使该上下文内的所有操作具有相同的设备分配。

# Creates a graph.
with tf.device('/cpu:0'):
  a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
  b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print(sess.run(c))

您会发现现在a和b被分配到cpu:0。由于MatMul操作没有明确指定设备,TensorFlow运行时将根据操作和可用设备选择一个设备(例如此示例中的gpu:0),并在必要时自动在设备之间复制张量。

Device mapping:
/job:localhost/replica:0/task:0/gpu:0 -> device: 0, name: Tesla K40c, pci bus
id: 0000:05:00.0
b: /job:localhost/replica:0/task:0/cpu:0
a: /job:localhost/replica:0/task:0/cpu:0
MatMul: /job:localhost/replica:0/task:0/gpu:0
[[ 22.  28.]
 [ 49.  64.]]

之前的回答2。

参见:使用GPU

在多GPU系统上使用单个GPU

如果您的系统中有多个GPU,则默认情况下将选择ID最低的GPU。 如果您想在不同的GPU上运行,则需要明确指定首选项:

# Creates a graph.
with tf.device('/gpu:2'):
  a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
  b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
  c = tf.matmul(a, b)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print sess.run(c)

早些时候的答案1。

来自CUDA_VISIBLE_DEVICES-Masking GPUs

你的CUDA应用程序需要针对特定的GPU吗?如果你正在编写GPU启用代码,你通常会使用设备查询来选择所需的GPU。但是,在测试时快速简单的解决方案是使用环境变量CUDA_VISIBLE_DEVICES来限制CUDA应用程序看到的设备。如果你尝试在节点上共享资源或者希望你的GPU启用可执行文件针对特定的GPU,则这可能很有用。

环境变量语法

结果

CUDA_VISIBLE_DEVICES = 1 只能看到设备1 CUDA_VISIBLE_DEVICES = 0,1 设备0和1将被显示 CUDA_VISIBLE_DEVICES =“0,1”与上面相同,引号是可选的 CUDA_VISIBLE_DEVICES = 0,2,3 设备0、2、3将被显示;设备1被屏蔽

CUDA将从零开始枚举可见的设备。在最后一种情况下,设备0、2、3将显示为设备0、1、2。如果您更改字符串的顺序为“2,3,0”,则设备2,3,0将分别枚举为0,1,2。如果CUDA_VISIBLE_DEVICES设置为不存在的设备,则所有设备都将被屏蔽。您可以指定一组有效和无效的设备编号。在无效值之前的所有设备都将被枚举,而在无效值之后的所有设备都将被屏蔽。

要确定系统中可用硬件的设备ID,您可以运行CUDA SDK中包含的NVIDIA deviceQuery可执行文件。祝你编程愉快!

克里斯·梅森


我做了完全相同的事情。但是当我执行nvidia-smi时,我发现所有GPU设备使用的内存量相等。 - Rajarshee Mitra
链接到TensorFlow GPU信息已经过时/失效;而是(截至2017/10)请尝试:https://www.tensorflow.org/tutorials/using_gpu - michael
@Michael 谢谢。已更新答案。 - Guy Coder
@GuyCoder:我对运行tensorflow-gpu代码也有类似的疑问。它正在使用所有的GPU,但为什么像多进程模块一样没有使用所有的核心呢?你能检查一下吗?https://stackoverflow.com/questions/54402154/how-to-achieve-gpu-parallelism-using-tensor-flow - Sooraj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接