TensorFlow之设备(device)详解

对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之设备(device)方法详解_执行流程

下面来一个简单的例子:

# 测试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)

TensorFlow之设备(device)方法详解_执行设备信息
我们可以发现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的显卡调用不了。
就拿自己的电脑举例吧,我的电脑有两个显卡:

  1. CPU的的集显(Intel),这个调用不了
  2. 英伟达(NVIDIA)的独显,这个可以调用

那么AMD和Intel或者其他显卡不能用来训练深度学习的模型呢?
因为其他的显卡内部是写死的,英伟达的显卡不是写死的,我们可以通过Python/C++调用CUDNN,从而进行矩阵运算。

另外你显卡的显存最好不要小于4G,原因嘛,算了又是一堆扯淡。

或者准确来说在TensorFlow的GPU版本中我们也很少调用GPU因为没有那个意义,在这种情况下,你这样那个GPU和CPU原理是一样的,因为他这里GPU是没有加速的,你等同于调了一个CPU,只有在TensorFlow的GPU版本中,我们才会分别调GPU和CPU。

有些操作只能在CPU下运算,所以我们才会在CPU下放入我们需要计算的东西,在这种场景下,我们才会用到这种设备(CPU)

既然这个东西在实际工作中作用不是太大,那么我们为什么会提到这个点呢?

因为我们更多的不是用它来调用本地资源,而是用它来调用分布式服务器资源,这就是另一回事了。