如何使用Julia重新思考ML工具,并对现代ML工具需要做的工作提供一些见解

随着机器学习等领域的飞速发展,亟需一门适用于该领域的编程语言。julia官方博客发文探讨了如何使用julia重新思考ml工具,并对现代需要做的工作提供了一些见解。
自从julia团队提出“需要一流的语言、编译器和机器学习(ml)生态系统”以来,该领域呈现出一些有趣的发展趋势。
在现有的系统如tensorflow或pytorch中,不仅权衡问题(tradeoff)没有得到解决,而且它们的“边界”比以往任何时候都更加明显,因为这两个框架都包含不同的“静态图(static graph)”和“动态图机制(eager execution)”接口。
在目前的框架还不够完善的情况下,一些激动人心的新项目如雨后春笋般出现,完全省去了图(graph),并将可微分编程(differentiable programming)引入主流:
theano团队的myia将python的一个子集区分并编译为高性能gpu代码;
swift for tensorflow扩展了swift,可以将兼容的函数编译为tensorflow图;
flux生态系统正在使用许多聚焦于ml的工具扩展julia的编译器,包括gradients、cuda内核编译、自动批处理以及对tpu等新硬件的支持。
所有这些项目都拥有巨大的潜力,但团队认为julia更有优势。
本文探讨了团队如何使用julia重新思考ml工具,并对现代ml工具需要做的工作提供一些见解。
flux加持,julia更适于机器学习
我们需要一种语言来编写可微算法,而flux使得julia成为了这样的一门语言。julia专为数学和数值计算而设计,非常适合表达ml算法。同时,它在编译器中融合了现代设计和新思想,更容易满足最前沿ml的高性能需求。
在典型的框架中,所有的内容需要用几十万行的c++代码来堆砌,而flux仅仅是几千行简单的julia代码。只需要一个用于gradient的包(zygote.jl),一个用于支持gpu的包(cuarrays.jl),“撒”上一些轻便的功能,“烘烤”十五分钟,便可弹出一个功能齐全的ml堆栈。
与其他下一代ml系统一样,flux致力于提供较为直观的界面,并对任何类型的图形构建或性能注释采取强硬措施。
julia支持flux所有特性,包括控制流、数据结构和宏等。用户可以在jupyter notebook上交互式编程,并将高性能数字与便捷的绘图、可视化做结合。
但julia也想获取传统“静态图”框架的优势——零开销的“源到源”ad、操作符融合、多gpu/分布式训练和单二进制(single-binary)部署。
这该如何实现呢?需要直接从julia编写的语法中提取和分析“静态图”,这实际上是编译器完全正常的工作。从某些角度来看,大多数ml系统问题都是经过深入研究的标准编译器问题。使用编译语言就足以解决许多问题,扩展编译器是解决更多问题的最佳方法。
在此只介绍这个领域当前工作中的一个示例—即获取梯度、编译gpu和tpu以及自动批处理。
采用“梯度”
我们突破了反向模式微分(reverse-mode differentiation)的极限,将其视为一个语言级别的问题。现有框架通过跟踪(tracing)来实现这一点。引入了一种新的张量类型,它记录了所执行的所有基本数学操作,产生了一个图形(或符号表达式),其中删除了主机语言的控制流和数据结构。
然而,这带来了一个困难的权衡:我们要么接受解释器的开销(eager execution),要么冻结用户控制流,并限制可以构建的模型的种类(static graphs)。
相反,如果图(graph)是julia自身的语法呢?
将这个想法发挥到极致,我们构建了zygote,它直接在ssa形式的ir上工作,并支持控制流,递归,数据结构和宏等语言功能。
然后,我们可以通过llvm之类的编译器生成的ssa形式的伴随代码,并将传统编译器优化的所有好处应用于我们的前向和反向传递。
此外,这种方法为扩展该编译器基础结构提供了机会,可以使用更高级和特定于域的优化,例如内核融合和编译到tpu等加速器。 swift for tensorflow和myia开发人员在源到源ad技术的复兴中正在探索类似的方法。
julia用于此任务的一个关键优势是它可用于实现基本数值库,如微分方程求解器或优化库; 这巧妙地解决了ml社区日益增长的需求,研究人员通过高性能代码(如光线跟踪器和物理引擎)反向传播,但gradient仍必须在c ++中手动实现。
相比之下,由于julia的实施是用julia编写的,所以从ode到金融定价模型(financial pricing model)的所有内容都可以轻松地进行区分。 将这些强大的工具带入模型是深度学习真正成为可微分编程的地方。
为gpu编写julia
gpu编程是现代ml的重要组成部分。框架在内部提供内核,但是用户只能看到有限的一组数学运算,不能直接对gpu进行编程。相比之下,julia中的gpu编程一直是一流的cuda内核(可以很好地编写并从脚本或笔记本中运行)。
一个简单的向量加法核看起来与cuda c等价。
functionkernel_vadd(a,b,c)i=(blockidx().x-1)*blockdim().x+threadidx().xc[i]=a[i]+b[i]returnend
但是,julia的类型特化(type specialization)可以在gpu上实现一组强大的附加抽象。例如,上面的代码并不局限于密集的浮点数组,而是可以给出稀疏的复数数组。
julia on tpus
谷歌最近开放了他们的云tpu使用的xla ir,使得ml以外的其他框架和用户都可以利用这个重量级硬件。 xla功能强大但有限:它无法运行python解释器,当然也没有良好的性能。 然后框架最终处于与gradient相似的位置,只能使用程序跟踪来撬开python,最终得到一个快速但更有限的ml语言。
而我们只需要从已经编写的julia程序中提取“静态图”并将其直接编译到xla,从而允许julia本身在tpu上运行。(实际上,这只是julia通常编译过程的一个简单扩展,该编译过程从程序中提取尽可能大的“静态子图”,然后将它们发送到llvm。)
这使我们可以充分利用julia语言的表现力,包括 控制流,递归,多调度,高阶函数,强大的数据结构和抽象,自定义数字类型,以及现有的包,如微分方程求解器和线性代数例程。所有这些工作都是在tpu中使用高性能收缩阵列引擎的同时进行的。
自动batching
为了从这些加速器中获得最大收益,批处理程序通常会同时将前向和反向传递应用于多个训练示例。在一些简单的情况下,比如卷积网络,通过将10张图像按照额外的批处理维度连接起来来处理这个问题是很简单的。但是在处理各种结构的输入(如树或图)时,这项任务变得更加困难。
大多数研究人员通过手工批处理代码来解决这一问题。针对不同的框架(dynet、tensorflow fold)提出了不同的解决方案,它们在可能的情况下尝试将一些高级操作批处理在一起,但是这些操作通常要么有自己的可用性问题,要么无法实现手工编写的代码的性能。
我们认为这个问题与单程序多数据(spmd)编程的问题是相同的,后者已经被语言和编译器社区研究了几十年,并且在最近的批处理方法(如matchbox)中变得很明显。实际上,它与gpu内部使用的并行模型非常相似,并且已经实现为cpu的simd单元的编译器变换。
从这项工作中获得灵感,我们正在julia中实现相同的转换,为标量simd单元和模型级批处理提供spmd编程。这使我们能够实现在单个示例上编写简单代码的理想,同时仍然在现代硬件上获得最佳性能。
总结
我们认为,机器学习的未来取决于语言和编译技术,特别是扩展新的或现有的语言,以满足ml研究的高要求。这不仅对ml社区有好处,对一般的数值编程也有好处;能够很好地支持差异化、向量化和外来硬件的语言将足以推动科学的许多进步。

美国开发新技术:可帮助激光雷达高分辨率地检测附近快速移动的物体
Vishay 推出经AEC-Q200认证的新款150W厚膜功率电阻器
adm2587e引脚功能介绍_adm2587e外围电路分析
博西家电正在践行本土化战略,以更快的速度让洗碗机融入到每个家庭
常用半导体二极管的主要参数
如何使用Julia重新思考ML工具,并对现代ML工具需要做的工作提供一些见解
三端稳压器件的扩流,Make the regulator output more current
设计一个5V 2A SMPS电路
安集科技三季报出炉,稳健缔造可持续蓝图
单片机最小系统的基本组成及主要功能
高频变压器与低频变压器的区别?
虹科监控一体化HMI解决工业物联网三大难题
华为P10最新消息:华为P10充电器起火事件,谁是谁非真假难辨,网友也参与进来
水下智能装备企业「深之蓝」宣布完成了2亿元Pre-IPO轮融资
华为海雀智能摄像头pro怎么样 拆解搭载海思芯片的海雀智能摄像头Pro
视频硬核解读安森美图像传感器各项关键成像技术
AI及物联网企业佳华科技发布2022第一季度报告
PCB设计后期检查的六个重点
国产CPU大腾飞前夜:从一场参加人员严重爆仓的大会说起
教你怎么选择智能汽车域控制器芯片?