百度飞桨于近期宣布,深度学习开源框架2.0 抢先版本正式发布,进入2.0时代。其中一项重大升级,就是推出更加成熟完备的命令式编程模式,即通常说的动态图模式。同时在该版本中将默认的开发模式定为动态图模式,满足用户直接使用该模式完成计算机视觉、自然语言处理、语音、推荐等全场景的AI算法开发。可见飞桨团队对采用动态图模式开发的成熟度,以及未来主力推广应用有着强大的自信和期待。
为什么飞桨在开发模式升级上持续大量投入?
动态图模式可以真正给广大开发者带来哪些实打实的好处?
本文将为你带来深度解读。
WHY动态图?
深度学习框架在编程界面上,一般有两种编程模式:命令式编程和声明式编程,即动态图和静态图。动态图模式下程序可即时执行并输出结果,编程体验和调试便捷性更佳;静态图模式下需完成整体网络结构的定义再执行,编程调试便捷性不够,但能够对全局编译优化,更有利于性能的提升,并天然利于模型保存和部署。
飞桨同时支持这两种编程模式,经过长期的深入技术探索和创新,已经实现同时兼顾两种方式的优势,达成了更有利于开发者的“动静统一的理想国”:
模型开发时,采用动态图模式,编程效率高调试方便;
模型训练部署时,支持动态图一键式自动转静态图,实现高性能训练,并无缝衔接模型存储和部署。
在飞桨开源框架最新版本上,该模式已经达到很高的成熟完备度。开发者既可体验到动态图开发模式带来的极大的便利性,用动态图实现深度学习领域最前沿的模型算法;又可享受到经过极致优化的运行效率,并且可以很容易的将动态图转换为静态图来进行推理和部署。
接下来将一一为你揭晓真实体验效果。
成熟完备的动态图开发模式带来便捷体验
成熟的动态图模式,可以为开发者带来极致体验,更优雅地编程。总结一下,便利性主要体现在以下三方面:
调试程序的便利性。在动态图开发模式下,用户运行飞桨提供的API后,可即时返回运行结果,不需要先创建计算图再运行,这样便于用户更加方便地组织代码,交互式地调试程序。
组建网络的高效性。在动态图开发模式下,用户可以使用Python的条件判断、循环等控制语句来执行模型算法的运算,不再需要使用静态图中的控制操作来执行运算,这样便于用户更加高效地组建网络。
构建模型的灵活性。在动态图开发模式下,用户可以根据控制流选择不同的分支网络,也可以更自然地构建权重共享的网络,更自然地实现自定义损失函数和循环网络、以及其他新颖的网络结构,从而灵活地进行深度学习模型的创新。
同时,在最新版本上,飞桨动态图提供了对计算机视觉、自然语言处理、推荐系统、语音识别等领域主流算法模型的全面支持,同时也对前沿的学术研究提供了非常好的支持。已开放的动态图模型数量达到了100+。这些模型都已开源在GitHub上,开发者可基于动态图模型进行AI应用开发和前沿学术研究:https://github.com/PaddlePadd...
更多飞桨动态图应用实践方法,欢迎访问飞桨官网文档。
极致优化的动态图运行效率享受卓越性能
飞桨对动态图运行效率的打磨,已持续数个版本,目前在主流的任务上,飞桨动态图执行模式已经能够达到与静态图媲美的水平,甚至达到业界领先水平。
在最新版本上,支持了自动混合精度和量化训练功能,在大幅提升效率的同时,保证最终模型的效果和原来的一致。以自动混合精度为例,代码实现如下:
import paddle
model = MyModel()
optimizer = paddle.optimizer.SGD(parameters=model.parameters())
scaler = paddle.amp.GradScaler(init_loss_scaling=1024) # initialize a GradScaler object
for data in data_loader():
with paddle.amp.auto_cast():
loss = model(data) # run in mixed precision
scaled = scaler.scale(loss) # scale the loss
scaled.backward() # do backward
scaler.minimize(optimizer, scaled) # update parameters
混合精度训练通过框架自动选择训练精度(AUTOMATIC CASTING)实现,过程如下图所示。对于模型的每个执行操作,AutoCast模块自动决定使用哪种精度的数据类型,例如:对于能够使用fp16进行(比如conv,relu 等op),会优先使用fp16来进行运算,来提升执行效率;但是对于使用fp16会影响精度的op(比如exp,softmax运算等op),会自动转换为fp32进行计算,保证收敛效果;对于单个op输入的数据类型不一致的情况,会通过自动的转换,使得能够能够支持运算。这些选择都是框架会自动进行的,用户仅需要调用上面示例的代码即可。
一行代码实现动转静,无缝衔接高速推理部署
飞桨框架最新版本的动转静功能,Python语法覆盖度处于业界领先水平,满足用户使用动态图编程调试、自动转静态图训练部署的需求;并且转换后性能几乎无损,实现媲美静态图的效果。
一行代码实现动转静。
动静转换的操作非常简单,仅需添加一个装饰器( @to_static ),框架就会自动将动态图的程序,转换为静态图的program,并使用该program训练、保存为静态图模型以实现推理部署。
import paddle
from paddle.static import InputSpec
from paddle.fluid.dygraph import Layer
from paddle.jit import to_static
class SimpleNet(Layer):
def __init__(self):
super(SimpleNet, self).__init__()
self.linear = paddle.nn.Linear(10, 3)
@to_static(input_spec=[InputSpec(shape=[None, 10], name='x'), InputSpec(shape=[3], name='y')])
def forward(self, x, y):
out = self.linear(x)
out = out + y
return out
net = SimpleNet()
paddle.jit.save(net, './simple_net')
飞桨动转静功能除了简单的一键式操作,还在进一步降低转换出错概率、提供便捷的转换诊断工具方面做了大量工作,为用户提供便捷的体验。
广覆盖Python语法,降低转换出错概率:飞桨通过将Python写的动态图代码转写为静态图代码,并在底层自动使用静态图执行器运行。这种转换方式使得用户可以灵活使用Python语法及控制流来构建神经网络模型,并且能够利用静态图的图优化策略进行加速。目前飞桨为用户提供以下几大类的语法支持,语法覆盖度处于业界领先水平:
控制流相关关键词,例如if-elif-else条件,while循环等;
运算类型,例如and、or、not逻辑运算,类型转化等;
Python函数相关,例如print,len,lambda表达式等;
报错异常相关,例如assert等;
Python基本容器,例如list,dict等。
提供转换Debug功能,便捷查看转换信息:为了方便开发者查看转换后的静态图代码是否符合预期,飞桨提供了类似编译器的易用功能来帮助用户:
报错信息对应到动态图代码行。
设置断点功能:通过 pdb.set_trace(),用户可以进行断点调试。
中间状态转换查看:飞桨框架为用户开放接口设定日志级别,让用户可以打印中间状态转换的代码。
查看转换后的静态图代码:飞桨框架为用户提供一个可以直接调用的StaticLayer class,可以让用户获取转换后的静态图代码。
动转静后性能媲美静态图。
性能方面,在保证用户一键轻松实现动态图转静态图的同时,动态图转静态图之后的推理性能和静态图完全一致,兼顾动态图易用性和静态图部署性能的需求。
闻说双飞桨,翩然下广津
以上即飞桨动态图模式的最新创新进展,动态图开发模式经过持续数个版本的打磨,无论是功能特性、易用性,还是性能水平,都达到了相当的成熟完备度,甚至达到业界领先水平。飞桨一直潜心于底层基础技术的深耕,坚持为企业用户和开发者提供最灵活易用的产业级深度学习框架,并以『用户体验的持续优化』和『产业实践的打磨』作为迭代向前的两个重要驱动轮。
未来飞桨的发展离不开广大开发者的加持,期待更多的开发者加入飞桨,飞桨也将持续完善动态图开发模式,开放更多动态图实现的领先算法模型,优化运行效率,为开发者进行模型开发和开展前沿创新工作提供助力,踏着飞桨的战船疾风向前。