动手学深度学习(十、深度学习计算性能)

动手学深度学习(十、深度学习计算性能)

一、命令式和符号式混合编程

命令式编程,它使用编程语句改变程序状态。虽然使用命令式编程很方便,但它的运行可能很慢。与命令式编程不同,符号式编程通常在计算流程完全定义好后才被执行。多个深度学习框架,如Theano和TensorFlow,都使用了符号式编程。通常,符号式编程的程序需要下面3个步骤:

  1. 定义计算流程;
  2. 把计算流程编译成可执行的程序;
  3. 给定输入,调用编译好的程序执行。
#命令式编程
def add(a, b):
    return a + b

def fancy_func(a, b, c, d):
    e = add(a, b)
    f = add(c, d)
    g = add(e, f)
    return g

print(fancy_func(1, 2, 3, 4)) # 10

#符号式编程
def add_str():
    return '''
def add(a, b):
    return a + b
'''

def fancy_func_str():
    return '''
def fancy_func(a, b, c, d):
    e = add(a, b)
    f = add(c, d)
    g = add(e, f)
    return g
'''

def evoke_str():
    return add_str() + fancy_func_str() + '''
print(fancy_func(1, 2, 3, 4))
'''

prog = evoke_str()
print(prog)
y = compile(prog, '', 'exec')
exec(y)

#输出:
10

def add(a, b):
    return a + b

def fancy_func(a, b, c, d):
    e = add(a, b)
    f = add(c, d)
    g = add(e, f)
    return g

print(fancy_func(1, 2, 3, 4))

10

以上定义的3个函数都仅以字符串的形式返回计算流程。最后,我们通过compile函数编译完整的计算流程并运行。由于在编译时系统能够完整地获取整个程序,因此有更多空间优化计算。

对比这两种编程方式,我们可以看到以下两点。

  • 命令式编程更方便。当我们在Python里使用命令式编程时,大部分代码编写起来都很直观。同时,命令式编程更容易调试。这是因为我们可以很方便地获取并打印所有的中间变量值,或者使用Python的调试工具。

  • 符号式编程更高效并更容易移植。一方面,在编译的时候系统容易做更多优化;另一方面,符号式编程可以将程序变成一个与Python无关的格式,从而可以使程序在非Python环境下运行,以避开Python解释器的性能问题。

大部分深度学习框架在命令式编程和符号式编程之间二选一。例如,Theano和受其启发的后来者TensorFlow使用了符号式编程,Chainer和它的追随者PyTorch使用了命令式编程,而Gluon则采用了混合式编程的方式。pytorch仅仅采用了命令式编程。

二、异步计算(略)

默认情况下,PyTorch中的 GPU 操作是异步的。当调用一个使用 GPU 的函数时,这些操作会在特定的设备上排队但不一定会在稍后立即执行。这就使我们可以并行更多的计算,包括 CPU 或其他 GPU 上的操作。 一般情况下,异步计算的效果对调用者是不可见的,因为(1)每个设备按照它们排队的顺序执行操作,(2)在 CPU 和 GPU 之间或两个 GPU 之间复制数据时,PyTorch会自动执行必要的同步操作。因此,计算将按每个操作同步执行的方式进行。 可以通过设置环境变量CUDA_LAUNCH_BLOCKING = 1来强制进行同步计算。当 GPU 产生error时,这可能非常有用。(异步执行时,只有在实际执行操作之后才会报告此类错误,因此堆栈跟踪不会显示请求的位置。)

三、自动并行计算

默认情况下,GPU 操作是异步的。当调用一个使用 GPU 的函数时,这些操作会在特定的设备上排队,但不一定会在稍后执行。这允许我们并行更多的计算,包括 CPU 或其他 GPU 上的操作。

torch.cuda.synchronize()    并行执行

当两个计算任务一起执行时,执行总时间小于它们分开执行的总和。这表明,PyTorch能有效地实现在不同设备上自动并行计算。

四、多GPU计算

这里我们谈论的是单主机多GPU计算而不是分布式计算。

扫描二维码关注公众号,回复: 13571415 查看本文章

我们将展示如何使用多块GPU计算,例如,使用多块GPU训练同一个模型。正如所期望的那样,运行本节中的程序需要至少2块GPU。事实上,一台机器上安装多块GPU很常见,这是因为主板上通常会有多个PCIe插槽。如果正确安装了NVIDIA驱动,我们可以通过在命令行输入nvidia-smi命令来查看当前计算机上的全部GPU。

import torch

net = torch.nn.DataParallel(net)
#net = torch.nn.DataParallel(net, device_ids = [0, 1])

print(net)

torch.save(net.module.state_dict(), "./8_4_model.pt")
new_net = torch.nn.Linear(10, 1)
new_net.load_state_dict(torch.load("./8_4_model.pt"))
print(new_net)

猜你喜欢

转载自blog.csdn.net/jiangchao98/article/details/115605927