对TensorFlow不了解的,猛的一看还以为TensorFlow是个设备什么的,其实本文要说的是Python的TensorFlow模块下一个叫device()的方法,即:
import tensorflow as tf
with tf.device('/gpu:0'):
...
...
...
设备是指一块可以用来运算并且拥有自己的地址空间的硬件,如CPU和GPU
TensorFlow为了在执行操作的时候充分利用计算资源,可以通过tf.device()
方法明确指定操作在哪个设备上执行.
一般情况下不需要显示指定使用CPU还是GPU,TensorFlow会自动检测.
如果检测到GPU,TensorFlow会尽可能地利用第一个GPU('/gpu:0'
)来执行操作.
注意:如果机器上有超过一个可用的GPU,那么除了第一个外其它GPU默认是不参与计算的.
所以,在实际TensorFlow编程中,经常需要明确给定使用的CPU和GPU.
你可以通过如下方式指定使用哪个设备:
-
"/cpu:0"
: 表示使用机器CPU运算 -
"/gpu:0"
: 表示使用第一个GPU运算,如果有的话 -
"/gpu:1"
: 表示使用第二个GPU运算,以此类推
TensorFlow集群(Cluster)是一系列能够对TensorFlow中的图(Graph
)进行分布式计算的任务(Task)。每个任务是同服务(Server
,你可以把它认识是服务器集群中的一台服务器)相关联的。
TensorFlow中的服务会包含一个用于创建Session
的主节点和至少一个用于图运算的工作节点。
另外在TensorFlow中,一个集群可以被拆分为一个或者多个作业(Job
),每个作业可以包含至少一个任务(Task)
就这样TensorFlow把整个运算过程层层分包,最终确定哪个设备执行哪个操作
如下图所示:
下面来一个简单的例子:
# 测试TensorFlow的分布式集群设备调用
# 2019年4月18日
import tensorflow as tf
if __name__ == '__main__':
mat1 = tf.constant([3, 3], dtype=tf.float32, shape=[1,2])
mat2 = tf.constant([[3.], [3.]])
product = tf.matmul(mat1, mat2)
# log_device_placement=True表示打印TensorFlow设备信息
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
sess.run(product)
我们可以发现Matmul
(乘法)操作先创建了一个job,这个job又创建了一个Task,这个Task又把这个操作分配给了CPU:0
去执行。
其实TensorFlow的CPU版本也能调用GPU,但是它少了个GPU加速,只有TensorFlow-gpu版本有GPU加速,因为GPU加速的原因,同一个程序,使用GPU版的TensorFlow可能会比CPU版的快100倍。
问题又来了,既然它能调用GPU,他是怎么去调用的呢?
这就和TensorFlow设备有关系了,设备(device)其实就是指你想调用哪个命名空间?然后就可以通过如下代码进行调用:
with tf.device('/gpu:0'):
a = tf.constant([1, 2, 3], name='a')
b = tf.constant(2, name='b')
c = a * b
# 新建Session
# log_device_placement=True表示打印TensorFlow设备信息
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
print(sess.run(c))
但是这也仅仅只能调用英伟达的显卡,英特尔的和AMD的显卡调用不了。
就拿自己的电脑举例吧,我的电脑有两个显卡:
- CPU的的集显(Intel),这个调用不了
- 英伟达(NVIDIA)的独显,这个可以调用
那么AMD和Intel或者其他显卡不能用来训练深度学习的模型呢?
因为其他的显卡内部是写死的,英伟达的显卡不是写死的,我们可以通过Python/C++调用CUDNN,从而进行矩阵运算。
另外你显卡的显存最好不要小于4G,原因嘛,算了又是一堆扯淡。
或者准确来说在TensorFlow的GPU版本中我们也很少调用GPU因为没有那个意义,在这种情况下,你这样那个GPU和CPU原理是一样的,因为他这里GPU是没有加速的,你等同于调了一个CPU,只有在TensorFlow的GPU版本中,我们才会分别调GPU和CPU。
有些操作只能在CPU下运算,所以我们才会在CPU下放入我们需要计算的东西,在这种场景下,我们才会用到这种设备(CPU)
既然这个东西在实际工作中作用不是太大,那么我们为什么会提到这个点呢?
因为我们更多的不是用它来调用本地资源,而是用它来调用分布式服务器资源,这就是另一回事了。