Julia加入TPU,这是一个靠自己亦要融入设备学习的编程语言
<div style="color: black; text-align: left; margin-bottom: 10px;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">选自arxiv,作者:Keno Fischer, Elliot Saba,<span style="color: black;">设备</span>之心编辑部。</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Julia 语言发展非常<span style="color: black;">快速</span>,它<span style="color: black;">能够</span>视为<span style="color: black;">同期</span>具备了 Python 的灵活性与 C 的速度,但<span style="color: black;">日前</span> TensorFlow 和 PyTorch 等框架官方都不支持 Julia 语言。<span style="color: black;">因此呢</span><span style="color: black;">近期</span>有<span style="color: black;">科研</span>者借助 XLA 底层编译器为 Julia 构建 TPU 支持,<span style="color: black;">她们</span><span style="color: black;">暗示</span>该<span style="color: black;">办法</span>能够将 Julia 程序编写的 VGG19 模型融合到 TPU 可执行文件中,并调用 TPU 实现<span style="color: black;">有效</span>计算。而 Google.ai 的负责人 Jeff Dean 在推特上<span style="color: black;">亦</span><span style="color: black;">暗示</span>「Julia + TPUs = fast and easily expressible ML computations!」</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">1. 引言</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">过去的几年里推动<span style="color: black;">设备</span>学习技术稳步发展的<span style="color: black;">基本</span>性改变之一是训练和优化<span style="color: black;">设备</span>学习模型的巨大计算力。许多技术都是很年前就<span style="color: black;">已然</span>提出,唯有近几年<span style="color: black;">提高</span>的计算力<span style="color: black;">能够</span>为现实世界的问题<span style="color: black;">供给</span>足够<span style="color: black;">优秀</span>的<span style="color: black;">处理</span><span style="color: black;">方法</span>。这些计算能力的很大一部分是<span style="color: black;">经过</span> GPU 获取的,其针对向量的计算能力最初是为图形而设计的,但<span style="color: black;">设备</span>学习模型<span style="color: black;">一般</span>需要执行<span style="color: black;">繁杂</span>的矩阵运算,<span style="color: black;">因此呢</span> GPU <span style="color: black;">一样</span>表现出了非常好的性能。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这些<span style="color: black;">办法</span>及 GPU 在现实世界,尤其是在<span style="color: black;">设备</span>学习<span style="color: black;">行业</span>的成功<span style="color: black;">诱发</span>了硬件设计者的一系列创新,<span style="color: black;">她们</span>致力于为<span style="color: black;">设备</span>学习工作负载<span style="color: black;">开发</span>新的加速器。然而,尽管 GPU 很长一段时间都在 CUDA 等软件系统发力,但这些库<span style="color: black;">一般</span>不会扩展到新的非 GPU 加速器,为这些加速器<span style="color: black;">研发</span>软件仍然是一大挑战。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">2017 年,谷歌宣布<span style="color: black;">她们</span>将<span style="color: black;">经过</span>云服务向<span style="color: black;">公众</span><span style="color: black;">供给</span><span style="color: black;">她们</span>专有的 TPU <span style="color: black;">设备</span>学习加速器。最初,TPU 的<span style="color: black;">运用</span>局限于<span style="color: black;">按照</span>谷歌 TensorFlow <span style="color: black;">设备</span>学习框架编写的应用。幸运的是,2018 年 9 月,谷歌<span style="color: black;">经过</span>底层 XLA(Accelerated Linear Algebra)编译器的 IR 开放了 TPU 的<span style="color: black;">拜访</span>权限。这个 IR 是一个通用的优化编译器,用于表达线性代数基元的任意计算,<span style="color: black;">因此呢</span>为<span style="color: black;">运用</span> TPU 的非 TensorFlow 用户以及非<span style="color: black;">设备</span>学习工作负载<span style="color: black;">供给</span>了良好的<span style="color: black;">基本</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在本文中,<span style="color: black;">咱们</span>介绍了<span style="color: black;">运用</span>这个接口编译通用 Julia 代码的初步工作,它们<span style="color: black;">能够</span>进一步<span style="color: black;">拜访</span>谷歌云的 TPU。这一<span style="color: black;">办法</span>与 TensorFlow(Abadi et al., 2016)采用的<span style="color: black;">办法</span>形成对比,后者<span style="color: black;">无</span>编译 python 代码,而是先用 Python 构建一个计算图,<span style="color: black;">而后</span>再对这个计算图进行编译。它在美学上类似于 JAX(Frostig et al., 2018),JAX 的<span style="color: black;">目的</span>是<span style="color: black;">经过</span>跟踪和 Offload 高级数组运算来 Offload Python 本身编写的计算。然而重要的是,<span style="color: black;">咱们</span>不依赖于<span style="color: black;">跟踪</span>,而是利用 Julia 的静态分析和编译能力来编译<span style="color: black;">全部</span>程序,<span style="color: black;">包含</span>传递到设备端的所有<span style="color: black;">掌控</span>流。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">值得一提的是,<span style="color: black;">咱们</span>的<span style="color: black;">办法</span><span style="color: black;">准许</span>用户在编写模型时充分利用 Julia 语言的表现力。这些表现力<span style="color: black;">重点</span><span style="color: black;">表现</span>在<span style="color: black;">有些</span>高级特征上,如多重派发、高阶函数和现有库,如微分方程求解器(Rackauckas & Nie,2017)和通用线性代数例程等。<span style="color: black;">因为</span><span style="color: black;">仅在</span>纯 Julia 代码上运行,<span style="color: black;">因此</span>它<span style="color: black;">亦</span>与 Zygote.jl(Innes, 2018)自动微分工具兼容,该工具能执行自动微分<span style="color: black;">做为</span>高级编译过程。总的<span style="color: black;">来讲</span>,<span style="color: black;">咱们</span>能够编译<span style="color: black;">运用</span> Flux <span style="color: black;">设备</span>学习框架编写的完整<span style="color: black;">设备</span>学习模型,将模型的前向、反向传播及训练回路融合成一个可执行文件,并 Offload 到 TPU 中。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">论文:Automatic Full Compilation of Julia Programs and ML Models to Cloud TPUs</strong></p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/1540440488147e68c37d82f~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1722689593&x-signature=bM41ccH02CZsqcp%2BrUcpoxfnvb4%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">论文链接:</p>https://arxiv.org/abs/1810.09868
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">摘要</strong>:谷歌的云 TPU 是一种前景广阔的新型<span style="color: black;">设备</span>学习工作负载硬件架构,近年来<span style="color: black;">已然</span>成就了谷歌<span style="color: black;">非常多</span>里程碑式的<span style="color: black;">设备</span>学习突破。如今,谷歌<span style="color: black;">已然</span>在其云平台上为<span style="color: black;">公众</span><span style="color: black;">供给</span> TPU,<span style="color: black;">近期</span>又进一步开放,<span style="color: black;">准许</span>非 TensorFlow 前端<span style="color: black;">运用</span>。<span style="color: black;">咱们</span>描述了一种<span style="color: black;">经过</span>这一新 API 及谷歌 XLA 编译器将 Julia 程序的适当部分 Offload 到 TPU 的<span style="color: black;">办法</span>和实现。<span style="color: black;">咱们</span>的<span style="color: black;">办法</span>能够将 Julia 程序编写的 VGG19 模型及其正向传播完全融合到单个 TPU 可执行文件中,以便 Offload 到设备上。<span style="color: black;">咱们</span>的<span style="color: black;">办法</span>与 Julia 代码上现有的基于编译器的自动微分技术很好地结合在<span style="color: black;">一块</span>,<span style="color: black;">因此呢</span><span style="color: black;">亦</span>能够自动<span style="color: black;">得到</span> VGG19 反向传播并采用类似的<span style="color: black;">办法</span>将其 Offload 到 TPU。<span style="color: black;">运用</span><span style="color: black;">咱们</span>的编译器<span style="color: black;">拜访</span> TPU,<span style="color: black;">咱们</span>能够在 0.23 秒内完成批量为 100 张图像的 VGG19 前向传播,而 CPU 上的原始模型则需要 52.4s。<span style="color: black;">咱们</span>的实现仅需不到 1000 行的 Julia 代码,无需<span style="color: black;">按照</span> TPU 对核心 Julia 编译器或任何其他 Julia 包进行特有的更改。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">5. 将 Julia 语义映射到 XLA</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">只要 Julia 程序是<span style="color: black;">根据</span> XLA 基元来编写的,<span style="color: black;">咱们</span>就能将其编译到 XLA。然而,Julia 程序不是<span style="color: black;">按照</span>晦涩难懂的 HLO 操作来编写的,而是<span style="color: black;">按照</span>由 Julia 基本库<span style="color: black;">供给</span>的函数和抽象来编写的。幸运的是,Julia <span style="color: black;">运用</span>了多重派发,使得<span style="color: black;">按照</span> HLO 操作来表达标准库的抽象变得容易。下面展示了几个简单的例子:</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/15404404881465d3b8fcd9d~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1722689593&x-signature=O%2BsR4WN1sr1%2FrWzx5KDbA6xNzCc%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">除了这些简单的操作以外,<span style="color: black;">咱们</span>还<span style="color: black;">供给</span>了高级数组抽象的实现,尤其是 mapreduce 和 broadcast。依据 HLO 操作实现的 broadcast 大<span style="color: black;">大概</span> 20 行代码,为节省空间起见,此处不予展开,但「mapreduce」的实现非常简单:</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/15404404881544c41adb588~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1722689593&x-signature=lXxM6B8u6zOaPwn9%2FE%2FHosqJH74%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">从上图<span style="color: black;">能够</span>看到将任意 Julia 函数<span style="color: black;">做为</span>静态计算运算的效果。<span style="color: black;">因为</span> Julia 对泛型抽象的依赖,它只需指定极<span style="color: black;">少许</span>定义,就能覆盖<span style="color: black;">海量</span> API。<span style="color: black;">详细</span><span style="color: black;">来讲</span>,从 mapreduce 的定义中,<span style="color: black;">咱们</span><span style="color: black;">能够</span>自动得到在 base 中所定义运算(如 sum 和 prod)的降维。事实上,获取足够的 API 覆盖来编译 VGG19 模型的前向传播和反向传播需要不到 200 行定义。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">5.1 结构映射</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">咱们</span>做了一个额外的识别。embedded IR 中的任意元组或 immutable 结构被映射至一个 XLA 元组,即 julia 值 1 + 2im(由两个整数结构<span style="color: black;">构成</span>的<span style="color: black;">繁杂</span>数字)将被映射至 XLA 元组 (s64[], s64[])。<span style="color: black;">咱们</span>在 XLA IR 的 Julia 嵌入中<span style="color: black;">保留</span>该结构类型,但很显然 XLA 不<span style="color: black;">认识</span> julia 类型,<span style="color: black;">因此呢</span>在<span style="color: black;">最后</span>的转换<span style="color: black;">过程</span>中这些类型被转换成适当的元组。类似地,(julia)元组构造函数(以及 immutable 结构的构造函数)变<span style="color: black;">成为了</span> XLA 的元组构件。元组引用(immutable 结构的字段引用)变<span style="color: black;">成为了</span> XLA 的元组引用。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">5.2 处理<span style="color: black;">掌控</span>流</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">有一个额外的<span style="color: black;">繁杂</span>问题<span style="color: black;">咱们</span>还没讨论:Julia <span style="color: black;">供给</span>的命令式<span style="color: black;">掌控</span>流和 XLA <span style="color: black;">供给</span>的函数式<span style="color: black;">掌控</span>流之间的语义不匹配。为<span style="color: black;">认识</span>决 if/else <span style="color: black;">掌控</span>流模块,<span style="color: black;">咱们</span>在 Julia 编译器的 SSA IR 中查看 φ 节点,<span style="color: black;">而后</span>将这些节点<span style="color: black;">做为</span> XLA 函数式<span style="color: black;">掌控</span>流的结果(<span style="color: black;">倘若</span>在同一个合并点存在多个 φ 节点,则<span style="color: black;">咱们</span>构造这些节点的元组)。<span style="color: black;">引起</span>计算流分化的<span style="color: black;">要求</span>变<span style="color: black;">成为了</span>函数式<span style="color: black;">掌控</span>流的<span style="color: black;">要求</span>,二者之间的任意计算都可<span style="color: black;">做为</span>函数调用。循环<span style="color: black;">掌控</span>流类似<span style="color: black;">要求</span><span style="color: black;">掌控</span>流的构建,<span style="color: black;">咱们</span>识别<span style="color: black;">掌控</span>流图的强连接区域,将其<span style="color: black;">做为</span>循环的主体。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">7 结果</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">7.2 VGG19 前向传播</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">咱们</span>的<span style="color: black;">第1</span>个<span style="color: black;">繁杂</span>示例是完整 VGG19 前向传播。<span style="color: black;">咱们</span><span style="color: black;">运用</span> Metalhead 包中的 VGG19 实现 (Mike Innes & Contributors, 2018),它利用 Flux (Innes & Contributors, 2017) 框架将<span style="color: black;">熟练</span>的<span style="color: black;">设备</span>学习层(卷积层、全连接层)转换成线性代数运算。但重要的是,Flux 框架中的<span style="color: black;">每一个</span>层只是<span style="color: black;">通常</span>的函数,它们<span style="color: black;">能够</span>反过来调用<span style="color: black;">通常</span>的线性代数运算。<span style="color: black;">因此呢</span>,Flux 中表达的<span style="color: black;">设备</span>学习模型(<span style="color: black;">包含</span> VGG19)只是<span style="color: black;">通常</span>的 Julia 函数,<span style="color: black;">因此呢</span>能够<span style="color: black;">运用</span>本论文介绍的<span style="color: black;">办法</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">咱们</span>的编译器能够完全推断、offload 和融合(fuse)VGG19 的<span style="color: black;">所有</span>前向传播。在 Julia 级别的优化之后,顶层函数的<span style="color: black;">最后</span> IR <span style="color: black;">包含</span> 181 个指令(<span style="color: black;">每一个</span> HloOp 都是具备适当推断的常数静态参数和适当形态推断的动态参数)。<span style="color: black;">每一个</span>级别计算的 HLO operands 总数是 183(多出的两个用于嵌入中<span style="color: black;">隐匿</span>的参数指令),29 个计算一共有 361 个 HLO operands,指令数详情见图 3。<span style="color: black;">因为</span><span style="color: black;">咱们</span>能够 offload <span style="color: black;">所有</span>前向传播计算,<span style="color: black;">因此呢</span> Julia 不参与任何<span style="color: black;">评定</span><span style="color: black;">过程</span>,从而<span style="color: black;">能够</span>同步执行其他任务(如为下一<span style="color: black;">准许</span>备数据)。<span style="color: black;">另外</span>,得到代码的性能仅受限于 XLA 生成的代码质量,不受限于前端(性能<span style="color: black;">评定</span>见 7.4)。<span style="color: black;">咱们</span>在 ImageNet 验证集上<span style="color: black;">评定</span>了 VGG19 模型,并验证了得到结果与原版 Metalhead 的结果相匹配,从而验证了生成的 XLA 代码准确性。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">7.3 VGG19 反向传播</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">为了获取反向传播,<span style="color: black;">咱们</span>利用基于 Zygote.jl 编译器的 AD 框架 (Innes, 2018)。Zygote 在 Julia 代码上运行,其输出<span style="color: black;">亦</span>是 Julia 函数(适合重新导入 Zygote 以获取更高阶的导数,<span style="color: black;">亦</span>适合编译成针对 TPU 的模型)。如下是一个<span style="color: black;">详细</span>示例:</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/154044048810743e8a1856d~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1722689593&x-signature=BYWDQaEtHo1swOnR%2BdpTTtadR64%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">即模型当前值和特定训练样本(<span style="color: black;">或</span>训练样本批)所对应的导数。<span style="color: black;">咱们</span><span style="color: black;">运用</span> sum <span style="color: black;">做为</span>损失函数的简单替代。意外的是,第 6 章介绍的类型推断修改<span style="color: black;">亦</span>能够<span style="color: black;">加强</span>所有 VGG19 反向传播的类型推断精度。至于前向传播,优化和未优化的指令总数如图 1 所示。反向传播生成的 XLA 指令<span style="color: black;">显著</span>多于前向传播,其最大贡献者之一便是 Zygote 的混合模式广播融合(mixed mode broadcast fusion)——在一个映射内核(map kernel)中<span style="color: black;">同期</span>计算前向传播和反向传播。<span style="color: black;">因为</span> XLA <span style="color: black;">日前</span>不支持来自一个映射指令的多个输出,该函数在多个映射指令上重复运行,<span style="color: black;">因此呢</span>后续需要清洗 XLA 的 DCE。<span style="color: black;">通常</span>,<span style="color: black;">咱们</span>的编译过程<span style="color: black;">处理</span>了 XLA 对映射指令的处理,<span style="color: black;">由于</span>在泛型代码中调用 Julia 映射和 broadcast 函数非常<span style="color: black;">广泛</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">7.4 在 TPU 上进行<span style="color: black;">评定</span></strong></p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/1540440488273a597dbcbfa~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1722689593&x-signature=gpqvGTTbumAOmwfTxNsIG9C8Xy8%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">图 2:<span style="color: black;">区别</span>批<span style="color: black;">体积</span>对应的 VGG19 前向传播时长。Flux CPU 是 Flux master/Julia master,但不<span style="color: black;">运用</span> XLA 编译器。PyTorch CPU 是同一 CPU 上的相同 PyTorch 模型。FluXLA CPU 是<span style="color: black;">咱们</span>的<span style="color: black;">科研</span>在 CPU 上的 xrt 实现;FluXLA TPU (total) 是端到端时间,和客户端报告的时间一致(<span style="color: black;">包含</span> kernel launch 开销和从谷歌云把数据迁移回来,<span style="color: black;">重视</span>由于额外的网络迁移,该<span style="color: black;">测绘</span>结果会<span style="color: black;">显现</span><span style="color: black;">极重</span>的变动);FluXLA TPU (compute) 是 TPU 上的总计算时间,和云分析器报告的时间一致(与 FluXLA TPU (total) <span style="color: black;">区别</span>,该<span style="color: black;">测绘</span>很稳定)。所有 CPU <span style="color: black;">测绘</span>基于支持 AVX512 的 Intel(R) Xeon(R) Silver 4114 CPU @ 2.20GHz CPU。可获取高达 20 个内核,且 CPU 基准不限于单个内核(即使在实践中,<span style="color: black;">亦</span>不是所有 CPU 基准都<span style="color: black;">运用</span>并行化)。TPU 基准仅限单个 TPU 内核。所有时间<span style="color: black;">最少</span>经过 4 次运行(除了 FluXLA CPU for N=100,<span style="color: black;">由于</span>它<span style="color: black;">没法</span>在 10 分钟内完成一次运行)。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/1540440488358b861c92692~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1722689593&x-signature=anfHrUn9YGq%2FU5TJZFs6jlSrfYY%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">图 3:被编译为 XLA 后,Metalhead.jl VGG19 前向传播和反向传播的指令数分解,上图展示了未优化(Julia 前端之后)和优化指令数(XLA 优化流程之后,与 CPU 后端所用流程类似,但<span style="color: black;">无</span> HLO fusion)。<span style="color: black;">每一个</span>指令数被进一步拆分为实体计算中的指令(E)和所有计算中的指令数(T)。</p>
</div>
你的话语如春风拂面,让我感到无比温暖。 请问、你好、求解、谁知道等。 楼主的文章深得我心,表示由衷的感谢! 说得好啊!我在外链论坛打滚这么多年,所谓阅人无数,就算没有见过猪走路,也总明白猪肉是啥味道的。 一看到楼主的气势,我就觉得楼主同在社区里灌水。
页:
[1]