深度学习(2)-计算性能
命令式编程和符号式编程
命令式编程(Imperative Programming)和符号式编程(Symbolic Programming)是两种不同的编程范式。命令式编程描述了计算机应该执行的具体步骤来达到预期的结果。这种编程方式侧重于描述“怎么做”,而不是“做什么”。符号式编程侧重于表达计算的本质,而不是具体的执行步骤。程序表达的是问题的解决方案,而不是具体的操作细节,代码通常只在完全定义了过程之后才执行计算。
异步计算
异步计算(Asynchronous Computing)是一种编程和计算模式,它允许程序在等待某些操作完成的同时继续执行其他任务。与同步计算不同,异步计算可以提高程序的响应性和性能,尤其是在处理 I/O 操作、网络请求、长时间运行的任务等情况时。
GPU,TPU,NPU
GPU即Graphics Processing Unit,中文名为图形处理单元。需要注意的是,GPU没有独立工作的能力,必须由CPU进行控制调用才能工作,且GPU的功耗一般比较高。TPU即Tensor Processing Unit,中文名为张量处理器,是谷歌在2015年6月的IO开发者大会上推出了为优化自身的TensorFlow框架而设计打造的一款计算神经网络专用芯片。NPU即Neural-network Processing Unit,中文名为神经网络处理器,它采用“数据驱动并行计算”的架构,特别擅长处理视频、图像类的海量多媒体数据。
并行计算
CUDA是NVIDIA提供的一种GPU并行计算框架。对于GPU本身的编程,使用的是CUDA语言来实现的。在编写程序中,当我们使用了 .cuda() 时,其功能是让我们的模型或者数据从CPU迁移到GPU上(默认是0号GPU)当中,通过GPU开始计算。
当我们的服务器上有多个GPU,我们应该指明我们使用的GPU是哪一块,如果我们不设置的话,tensor.cuda()方法会默认将tensor保存到第一块GPU上,等价于tensor.cuda(0)。
PyTorch提供了两种多卡训练的方式,分别为DataParallel和DistributedDataParallel(以下我们分别简称为DP和DDP)。这两种方法中官方更推荐我们使用DDP,因为它的性能更好。DP只能在单机上使用,且DP是单进程多线程的实现方式,比DDP多进程多线程的方式会效率低一些。
首先我们来看单机多卡DP,通常使用一种叫做数据并行 (Data parallelism) 的策略,即将计算任务划分成多个子任务并在多个GPU卡上同时执行这些子任务。主要使用到了nn.DataParallel函数。1
2
3
4
5model = Net()
model.cuda() # 模型显示转移到CUDA上
if torch.cuda.device_count() > 1: # 含有多张GPU的卡
model = nn.DataParallel(model, device_ids=[0,1]) # 单机多卡DP训练
不过通过DP进行分布式多卡训练的方式容易造成负载不均衡,有可能第一块GPU显存占用更多,因为输出默认都会被gather到第一块GPU上。为此Pytorch也提供了torch.nn.parallel.DistributedDataParallel(DDP)方法来解决这个问题。
针对每个GPU,启动一个进程,然后这些进程在最开始的时候会保持一致(模型的初始化参数也一致,每个进程拥有自己的优化器),同时在更新模型的时候,梯度传播也是完全一致的,这样就可以保证任何一个GPU上面的模型参数就是完全一致的,所以这样就不会出现DataParallel那样显存不均衡的问题。
参考文献
https://zh.d2l.ai/chapter_computational-performance/index.html
深度学习(2)-计算性能
install_url
to use ShareThis. Please set it in _config.yml
.