动态尺寸模型优化实践之Shape Constraint IR Part II

简介: 在本系列分享中我们将介绍BladeDISC在动态shape语义下做性能优化的一些实践和思考。本次分享的是我们最近开展的有关shape constraint IR的工作,Part II 中我们将介绍shape constraint IR的设计,实现以及一些初步的实验结果

在本系列分享中我们将介绍BladeDISC在动态shape语义下做性能优化的一些实践和思考。本次分享的是我们最近开展的有关shape constraint IR的工作,鉴于篇幅较长,为了提升阅读体验,我们将分享拆分为两个部分:

  • Part I 中我们将介绍问题的背景,面临的主要挑战和以及我们做shape constraint IR的动机;
  • Part II 中我们将介绍shape constraint IR的设计,实现以及一些初步的实验结果;

本篇是关于Part II的介绍,Part I的介绍请参考这里

设计和实现

shape constraint IR的设计

使用IR来建模shape constraint并不是一个很容易的事情。我们需要设计一种方案既方便我们做shape constraint分析,同时又不会使得IR的后续变换变的很复杂。经过多次迭代之后,我们选择了type-based方案来构建shape constraint IR,基本思路如下段伪IR所示。

// original data-computation IR
func @main() {
  ...
  %0 = any_dialect.any_operation(...) : tensor<?x?xf32, [@S0, @S1]>
  ...
}
disc_shape.SymbolicDim @S0 {
  range list : [[...], [...], ...]
  likely_values : [...]
  ...
  symbolic_shape_graph: @shape_constraint_graph
}
disc_shape.SymbolicDim @S1 {
  range list : [[...], [...], ...]
  likely_values : [...]
  ...
  symbolic_shape_graph: @shape_constraint_graph
}
// A separated function to store shape constraint predicates between different symbolic dimensions.
// Each symbolic dim is either bound to a `disc_shape.dim` op or `disc_shape.bind_dim`
func @shape_constraint_graph(...) {
  %0 = disc_shape.dim() {ref: @S0} : index
  %1 = disc_shape.dim() {ref: @S1} : index
  disc_shape.tie_predicate_divisible(d0, d1) // d0 % d1 == 0
  // other tie_* ops
  //   disc_shape.tie_predicate_eq(d0, d1)  // d0 == d1
  //   disc_shape.tie_predicate_lt(d0, d1)  // dim less than
  //   disc_shape.tie_predicate_mul_eq(d0, d1, d2, ...) // d0 = d1 * d2 * ...
  //   // d0 * d1 = s0 * s1
  //   disc_shape.tie_predicate_product_eq([d0, d1, ..], [s0, s1, ...])
  //   // d0 = affine.apply(d1, d2, ...) {affine_attr = ...}
  //   disc_shape.tie_predicate_affine_eq(d0, d1, d2, ...) {affine_attr = ...}
}

在这个方案中,每一个symbolic dimension size(也即在编译期间无法确定具体大小的dimension size)对应一个全局的disc_shape.SymbolicDimIR对象。该IR对象中存储了关于这个symbolic dimension size的分布相关的约束,同时也存储了对一个shape constraint function的引用。在上图中最下面的部分是一个shape constraint function的例子。在这个function中存储的是symbolic dimension dim之间的相关关系(结构化约束),每一种相关关系用一个op来抽象,比如说这个例子中说展示的整除等价关系便是由tie_predicate_divisibleop来描述。选择type-based方案主data计算图中并不会直接存储shape constraint信息。在上图中的最上面是一个主data计算图的例子。主data计算图中,每一个tensor对应的type中都包含一个attribute,这个attribuet中存储了这个tensor所对应的symblic dimension size的引用。


通过将描述shape constraint的IR和主data计算IR解耦开,一方面可以尽可能减少对已有pattern匹配的逻辑的干扰 (matmul+BiadAdd -> FusedMatmulBiasAdd这个pattern替换并不需要感知到shape constraint IR的存在),另外一方面,不同层级的data计算的IR,比如tensor level IR和buffer level IR,可以用同一套shape constraint的描述。从而可以缓解IR lowering过程中shape constraint信息的丢失问题。

基于shape constraint IR的优化pipeline

将shape constraint IR作为第一等公民引入IR中之后,我们进一步构建了以shape constraint 为中心的优化 pipeline(如下图所示)。通过对shape constraint的充分的挖掘,而非依赖于具体的shape的值来辅助完成各种优化,从而实现在动态shape语义下尽可能接近静态shape优化工具的性能。

下图中展示了目前BladeDISC中主要的几个优化的阶段。从最左边开始看起。第一步是将前端AI框架的计算图lower到MHLO的计算描述。这里值得注意的是除了普通的data计算的lowering,还包含shape constraint的lowering,从而避免在动态shape语义信息的丢失。到MHLO之后,我们首先会完成shape constraint的分析以及分析结果的IR化表示。分析得到的结果将可以指导我们完成计算图上的一些基本化简,比如冗余broadcast op的消除,layout调整等。优化完之后的计算图,我们会进一步对其中的访存密集型算子做融合优化,shape constraint将是决定那些算子可以融合的很重要的判断依据,通过更充分的挖掘shape constraint,我们可以找到更多融合的机会。最后在做代码生成的时候,我们发现在动态shape语义下index计算的开销更加容易成为瓶颈,尤其是当算子融合的数目比较多的时候,利用shape constraint我们可以大幅消除冗余的index计算。以上限制于篇幅并未一一展开进行介绍,感兴趣的同学可以通过这里了解更多的细节。

初步测试

我们目前已经完成了shape constraint IR的第一阶段开发,也即shape constraint IR的引入以及pass pipeline的适配性改造。第一阶段的主要目标是搭建好整体的架子,还并未包含所有设计中优化的实现 (比如likely value的应用),我们将会在后续持续迭代完善shape constraint IR。在以上前提下,我们在一些比较典型的模型上完成初步的评测,下图展示的是部分的评测结果。由于目前shape constraint IR还未应用到计算密集型算子(GEMM/CONV等)的优化 ,故以下测评针对的是模型中访存密集型部分,主要从两个维度来衡量:

  • 访存密集型部分kernel launch的次数,即衡量fusion的粒度,同等情况下次数越少,fusion的粒度越大;
  • 访存密集型部分总消耗时间,即衡量生成的kernel的质量,同等情况下总时间越短,质量越高;

如下图中所示,在CPU和GPU上我们都观测到fusion粒度的明显改善以及访存密集型部分总消耗时间的减少。

合作讨论

以上是近期我们在shape constraint IR Part II的分享,更多相关信息欢迎加入BladeDISC用户群交流讨论。

相关实践学习
使用PAI+LLaMA Factory微调Qwen2-VL模型,搭建文旅领域知识问答机器人
使用PAI和LLaMA Factory框架,基于全参方法微调 Qwen2-VL模型,使其能够进行文旅领域知识问答,同时通过人工测试验证了微调的效果。
机器学习概览及常见算法
机器学习(Machine Learning, ML)是人工智能的核心,专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能,它是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域。 本课程将带你入门机器学习,掌握机器学习的概念和常用的算法。
相关文章
|
域名解析 jenkins Java
Jenkins的安装与升级
Jenkins的安装与升级
504 0
|
人工智能 算法 PyTorch
TorchAcc:基于 TorchXLA 的分布式训练框架
阿里云研究员、阿里云人工智能平台 PAI 技术负责人--林伟在GTC 2024 大会 China AI Day 线上中文演讲专场上介绍了TorchAcc,这是一个基于 PyTorch/XLA 的大模型分布式训练框架。
|
Shell Linux C语言
【Shell 命令集合 系统设置 】⭐⭐⭐Linux 清除终端屏幕内容 clear命令 使用指南
【Shell 命令集合 系统设置 】⭐⭐⭐Linux 清除终端屏幕内容 clear命令 使用指南
469 0
|
12月前
|
存储 机器学习/深度学习 人工智能
轻松实现向量搜索:探索 Elastic-Embedding-Searcher 项目
elastic-embedding-searcher 是一个基于 Elasticsearch 的向量搜索框架,简化了向量数据的存储和检索过程。通过结合 Elasticsearch 的分布式能力与向量表示,项目实现了高效、精准的相似度检索。支持多种流行的嵌入模型(如 BERT、Word2Vec),并能够处理大规模数据集。该项目适用于文本相似度检索、问答系统及多语言处理等场景,开发者可以轻松集成并实现高效的数据检索。
435 2
|
机器学习/深度学习 人工智能 前端开发
BladeDISC 深度学习编译器问题之在动态shape下优化整体性能如何解决
BladeDISC 深度学习编译器问题之在动态shape下优化整体性能如何解决
|
机器学习/深度学习 人工智能 编解码
课时1;跨越N次元 一键变身AI漫画人
课时1;跨越N次元 一键变身AI漫画人
|
9月前
|
PyTorch 编译器 算法框架/工具
NPU上如何使能pytorch图模式
本文介绍了PyTorch的`torch.compile`技术和TorchAir的相关内容。`torch.compile`通过将动态图转换为静态图并结合JIT编译,提升模型推理和训练效率。示例代码展示了如何使用`torch.compile`优化模型。TorchAir是昇腾为PyTorch提供的图模式扩展库,支持在昇腾设备上进行高效训练和推理。它基于Dynamo特性,将计算图转换为Ascend IR,并通过图引擎优化执行。文章还提供了TorchAir的使用示例及功能配置方法。
|
存储 人工智能 编译器
【AI系统】算子手工优化
本文深入探讨了手写算子调度的关键因素及高性能算子库的介绍,通过计算分析指标和 RoofLine 模型评估计算与访存瓶颈,提出了循环、指令、存储三大优化策略,并介绍了 TVM 和 Triton 两种 DSL 开发算子的方法及其在实际应用中的表现。
725 2
【AI系统】算子手工优化
|
12月前
|
机器学习/深度学习 人工智能 算法
【AI系统】AI 框架之争
本文介绍了AI框架在数学上对自动微分的表达和处理,以及其在多线程算子加速、GPU/NPU支持、代码编译优化等方面的技术挑战。文章详细梳理了AI框架的发展历程,从萌芽阶段到深化阶段,探讨了不同阶段的关键技术和代表性框架。同时,文章展望了AI框架的未来趋势,包括全场景支持、易用性提升、大规模分布式支持和科学计算融合。
405 0
|
机器学习/深度学习 自然语言处理 监控
金融行业的大数据风控模型:构建安全高效的信用评估体系
金融机构借助大数据风控提升信贷效率,通过数据收集、清洗、特征工程、模型构建与评估来识别风险。关键技术涉及机器学习、深度学习、NLP和实时处理。以下是一个Python风控模型构建的简例,展示了从数据预处理到模型训练、评估的过程,并提及实时监控预警的重要性。该文旨在阐述大数据风控的核心要素和关键技术,并提供基础的代码实现概念。【6月更文挑战第23天】
2159 8

热门文章

最新文章