我的机器中有三块 GTX Titan GPU。我运行了 Cifar10 示例中的 cifar10_train.py,并得到了以下输出:
I tensorflow/core/common_runtime/gpu/gpu_init.cc:60] cannot enable peer access from device ordinal 0 to device ordinal 1I tensorflow/core/common_runtime/gpu/gpu_init.cc:60] cannot enable peer access from device ordinal 1 to device ordinal 0I 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 一样运行)
回答:
参见: 使用 GPU
手动设备分配
如果您希望某个操作在您选择的设备上运行,而不是自动选择的设备,您可以使用 tf.device
创建一个设备上下文,这样该上下文中的所有操作将具有相同的设备分配。
# 创建一个图。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)# 创建一个会话,并将 log_device_placement 设置为 True。sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))# 运行操作。print(sess.run(c))
您会看到现在 a 和 b 被分配到 cpu:0
。由于没有为 MatMul
操作明确指定设备,TensorFlow 运行时将根据操作和可用设备(本例中为 gpu:0)选择一个设备,并在需要时自动在设备之间复制张量。
设备映射:/job:localhost/replica:0/task:0/gpu:0 -> device: 0, name: Tesla K40c, pci busid: 0000:05:00.0b: /job:localhost/replica:0/task:0/cpu:0a: /job:localhost/replica:0/task:0/cpu:0MatMul: /job:localhost/replica:0/task:0/gpu:0[[ 22. 28.] [ 49. 64.]]
早期回答 2。
参见: 使用 GPU
在多 GPU 系统上使用单个 GPU
如果您的系统中有多个 GPU,默认情况下将选择 ID 最低的 GPU。如果您希望在不同的 GPU 上运行,则需要明确指定偏好:
# 创建一个图。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)# 创建一个会话,并将 log_device_placement 设置为 True。sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))# 运行操作。print sess.run(c)
早期回答 1。
来自 CUDA_VISIBLE_DEVICES – 屏蔽 GPU
您的 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,您可以运行 NVIDIA 的 CUDA SDK 中包含的 deviceQuery 可执行文件。祝您编程愉快!
Chris Mason