派大星 · 2022年11月17日 · 北京市

AMD Composable Kernel 大幅提升端到端Transformer性能

— 机器之心编译 —

Composable Kernel(CK)库旨在提供一套在AMD GPU 上算子融合的后端方案,该研究希望未来能够移植到 AMD 的所有 GPU 上,并且最终也可以被移植到 AMD CPU 上,该项目已开源

此外,CK库与Meta AITemplate的深度合作大幅提升了AI模型在AMD GPU的端到端性能。

AITemplate 是一个能把 AI 模型转换成高性能 C++ GPU 模板代码的 Python 框架。该框架在设计上专注于性能和简化系统。AITemplate 系统一共分为两层:前端部分进行图优化,后端部分针对目标 GPU 生成 C++ 模板代码。AITemplate 不依赖任何额外的库或 Runtime,如 cuBLAS、cudnn、rocBLAS、MIOpen、TensorRT、MIGraphX 等。

image.png

图1 BERT类模型AMD MI250性能 vs. FasterTransformer A100性能比较

图优化在降低 AI 模型的训练和推理使用的时间和资源方面起着重要作用。图优化的一个重要功能是模型中将可以融合的算子进行融合,通过降低内存占用和减少数据在低速内存中的搬运来提高计算效率。然而,实现一套能够提供各种算子融合的后端方案难度很大,导致在实际硬件上 AI 模型能够使用的算子融合非常有限。

Composable Kernel (CK)库旨在提供一套在 AMD GPU 上的算子融合的后端方案。CK 使用通用编程语言 HIP C++,完全开源。其设计理念包括:

  • 高性能& 高生产力:CK 的核心是一组精心设计,高度优化,可复用的基础模块。CK 库内所有的算子都是通过组合这些基础模块实现的。复用这些基础模块大大缩短开发后端算法的周期,同时还能保证高性能。
  • 精通当前的 AI 问题,快速适应未来的 AI 问题:CK 旨在提供一套完整的 AI 算子后端方案,这让复杂的算子融合成为可能,因为这样让整个后端都可以用 CK 实现,而不需依赖外部算子库。CK 的可复用基础模块足以实现常见 AI 模型(机器视觉,自然语言处理,等等)所需的各种算子及其融合。当新出现的 AI 模型需要新的算子时,CK 也将会提供所需的基础模块(复用已有模块需要对已有模块的API很熟悉,对新算子也需要人力跟进)
  • AI 系统专家的简单但强大的工具:CK 所有的算子都是用 HIP C++ 模版实现的。AI 系统专家可以通过实例化模版来定制这些算子的属性,比如数据类型,元操作类型,张量存储格式,等等。这通常只需要几行代码(听起来HIP C++的扩展和表达能力很强)
  • 友好的 HIP C++ 界面:HPC 算法开发者一直在推动着 AI 计算加速的前沿。CK 的一个重要设计理念就是要让 HPC 算法开发者更容易对 AI 加速作出贡献。因此CK 所有核心模块都是用 HIP C++ 实现,而不是 Intermediate Representation (IR)。HPC 算法开发者直接以他们熟悉的编写 C++ 代码的形式编写算法,而无需像基于 IR 的算子库那样,以通过编写针对某种特定算法的 Compiler Pass 来实现。这样做可以大大提高算法的迭代速度。
  • 可移植性:今天使用 CK 作为后端的图优化将能够移植到未来 AMD 的所有的 GPU上,并且最终也可以被移植到AMD CPU上【2】。

image.png

核心概念

CK 引入了两个概念:Tensor Coordinate Transformation 和 Tile Tensor Operator ,二者共同组成了 CK 的可复用的基础模块。

1.开创性的引入“张量坐标变换”(Tensor Coordinate Transformation)降低 AI 算子的编写复杂度。该研究开创性地定义了一组可复用的 Tensor Coordinate Transformation 基础模块,并且用它们把复杂的 AI 算子(比如卷积,group normalization reduction,Depth2Space,等等)以数学严谨的方式重新表达成了最基础的 AI 算子(GEMM,2D reduction,tensor transfer,等等)。
image.png
图1 使用 CK 的 Tensor Coordinate Transformation 基础模块将 convolution 算子表达成 GEMM 算子

这项技术可以让为基础 AI 算子编写的算法直接被用到所有与之对应的复杂的 AI 算子上,而无需重写算法。

2.基于 Tile 的编程范式:开发算子融合的后端算法可以被看成先将每一个融合前的算子(独立算子)拆解成许多 “小块” 的数据操作,然后再把这些“小块” 操作组合成融合的算子。每一个这样的 “小块” 操作都对应一个原始的独立算子,但是被操作的数据只是原始张量的一部分(tile),因此这样的 “小块” 操作被称为 Tile Tensor Operator。
image.png
图2 CK 的组成(下:可复用的基础模块;上:独立算子与融合算子)

CK 库包含一组针对 Tile Tensor Operator 的高度优化的实现,CK 里所有的 AI 独立算子和融合算子都是用它们实现的。目前,这些Tile Tensor Operators 包括 Tile GEMM,Tile Reduction 和 Tile Tensor Transfer每一个 Tile Tensor Operator 都有针对 GPU thread block,warp 和 thread 的实现

image.png

图3 Composable Kernel Overview

代码结构

CK 库结构分为四层,从下到上分别是Templated Tile OperatorTemplated Kernel and InvokerInstantiated Kernel and InvokerClient API【3】。每一层对应不同的开发者:

  • AI 系统专家:“我需要一个后端方案提供高性能的独立和融合算子让我可以直接使用”。这个例子【4】里用的Client API 和 Instantiated Kernel and Invoker提供了预先实例化并编译好的对象,以满足这类开发者的需求。
  • AI 系统专家:“我为一个开源的 AI 框架做最先进的图优化工作。我需要一个能够为图优化所需的所有融合算子提供高性能 kernel 的后端方案。同时我也需要定制这些 kernel,所以像 “要么接受,要么弃用” 的黑盒解决方案不能满足我的需求”。Templated Kernel and Invoker 层能满足这类开发者。比如这个例子【5】中开发者可以自己使用 Templated Kernel and Invoker 层实例化出所需的 FP16 的 GEMM + Add + Add + FastGeLU 的 kernel
  • HPC 算法专家:“我的团队为公司内部不断迭代的 AI 模型开发高性能后端算法。我们团队中有 HPC 算法专家,但我们仍然希望可以通过复用和改进硬件供应商提供的高度优化的源代码来提高我们的生产力,并且让我们的代码可以被移植到未来的硬件构架上。我们希望可以不用通过与硬件提供商分享我们的代码来做到这点”。Templated Tile Operator层可以帮助到这一类开发者。比如这个代码【6】中开发者使用 Templated Tile Operator 来实现 GEMM 的优化管线

image.png
图4 CK 库四层结构

基于 AITemplate + CK 的端到端模型推理

Meta 的 AITemplate 【7】(AIT)是一个统一 AMD 和 Nvidia GPU 的 AI 推理系统。AITemplate 使用 CK 作为其 AMD GPU 上的后端,它使用的是 CK 的 Templated Kernel and Invoker 层。

AITemplate + CK 在 AMD Instinct™ MI250 上取得了多个重要 AI 模型最先进的推理性能。CK 里大多数先进的融合算子的定义,都是在 AITemplate 团队的远见下推动的。许多融合算子的算法也是由 CK 和 AITemplate 团队共同设计

本文比较了几个端到端模型在 AMD Instinct MI250 和同级别产品【8】的性能表现。本文中所有 AMD Instinct MI250 的 AI 模型的性能数据都是用 AITemplate【9】 + CK【10】取得的。

实验

ResNet-50

下图显示了 AMD Instinct MI250 上的 AIT + CK 与 A100-PCIe-40GB 和 A100-DGX-80GB 上的 TensorRT v8.5.0.12 【11】(TRT)的性能比较。
image.png
结果显示AMD Instinct MI250 上的 AIT + CK 取得了相比于 A100-PCIe-40GB 上的 TRT 1.08 倍的加速

BERT

一个基于 CK 实现的 Batched GEMM + Softmax + GEMM 融合算子模版,可以完全消除掉中间结果在 GPU 计算单元(Compute Unit)与 HBM 之间的搬运。通过使用这个融合算子模版,attention layer 许多原本是带宽瓶颈(bandwidth bound)的问题变成了计算瓶颈(compute bound)的问题,这样可以更好发挥 GPU 的计算能力。这个 CK 的实现深受 FlashAttention 【12】的启发,并比原始的 FlashAttention 的实现减少了更多的数据搬运

下图显示了 AMD Instinct MI250 上的 AIT + CK 与 A100-PCIe-40GB 和 A100-DGX-80GB 上的 FasterTransformer v5.1.1 bug fix 【13】(FT)的 Bert Base 模型(uncased)的性能比较。当 Sequence 是 4096 时,FT 在 A100-PCIe-40GB 和 A100-DGX-80GB 上会在 Batch 32 时 GPU 内存溢出。因此,在 Sequence 是 4096 时,本文只显示 Batch 16 的结果。

image.png

结果显示AMD Instinct MI250 上的 AIT + CK 取得了相比于 A100-PCIe-40GB 上的 FT 3.28 倍,以及相比于 A100-DGX-80GB 上的 FT 2.91 倍的加速

Vision Transformer (VIT)

下图显示了 AMD Instinct MI250 上的 AIT + CK 与 A100-PCIe-40GB 和 A100-DGX-80GB 上的 TensorRT v8.5.0.12(TRT)的 Vision Transformer Base (224x224 图片)的性能比较。
image.png
结果显示AMD Instinct MI250 上的 AIT + CK 取得了相比于 A100-PCIe-40GB 上的 TRT 1.8 倍,以及相比于 A100-DGX-80GB 上的 TRT 1.4 倍的加速

Stable Diffusion

端到端的 Stable Diffusion

下表显示 AIT + CK 在 AMD Instinct MI250 上 Stable Diffusion 端到端(Batch 1,2,4, 6)的性能数据。当 Batch 是 1 时,在 MI250 上只有一个 GCD 被使用,而在 Batch 2,4,6 时,两个 GCD 都被使用了。

image.png

Stable Diffusion 中的 UNet

不过本文还没有关于使用 TensorRT 运行 Stable Diffusion 端到端模型的公开的信息。但这篇文章“Make stable diffusion 25% faster using TensorRT” 【14】说明了怎么使用 TensorRT 加速 Stable Diffusion 中的 UNet 模型。UNet 是 Stable Diffusion 中最重要最花时间的部分,因此UNet 的性能大致反应了 Stable Diffusion 的性能

下图显示了 AMD Instinct MI250 上的 AIT + CK 与 A100-PCIe-40GB 和 A100-DGX-80GB 上的 TensorRT v8.5.0.12(TRT)的 UNet 的性能比较。

image.png

结果显示AMD Instinct MI250 上的 AIT + CK 取得了相比于 A100-PCIe-40GB 上的 TRT 2.45 倍,以及相比于 A100-DGX-80GB 上的 TRT 2.03 倍的加速

算子开发伪代码

image.png
图5 Transform a forward convolution operator into a GEMM operator

原文链接

作者:AMD
文章来源:NeuralTalk

推荐阅读

更多嵌入式AI干货请关注 嵌入式AI 专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
16356
内容数
1226
嵌入式端AI,包括AI算法在推理框架Tengine,MNN,NCNN,PaddlePaddle及相关芯片上的实现。欢迎加入微信交流群,微信号:aijishu20(备注:嵌入式)
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息