【AI编译器】triton学习:编程模型

介绍

动机

在过去十年里,深度神经网络 (DNNs) 已成为机器学习 (ML) 模型的一个重要分支,能够实现跨领域多种应用中的最佳性能。这些模型由一系列包括参数化(如滤波器)和非参数化(如缩小值函数)元件组成的层次结构组成,这种模式虽然运算复杂度高且计算量大,但对于多核、并行处理器来说是非常适用的。

由于深度神经网络的计算能力和 GPU编程带来了极高的难度,因此对特定应用语言 (DSL)及编译器引发出广泛的学术与产业界兴趣。可惜的是,这些系统——无论是采用多面体结构(例如:Tiramisu [BAGHDADI2021]、 Tensor Comprehensions [VASILACHE2018 ])还是计划语言(例如:Halide[JRK2013]、TVM [CHEN2018])的——与库中的cuBLAS、cuDNN或TensorRT等核心数据处理库中的算法相比,速度往往远低。

本项目的主要前提是:基于blocked算法的编程范式 [LAM1991] 可以促进神经网络高性能计算内核的构建。

重新考察了传统GPU上“单程序多数据”(SPMD[AUGUIN,1983])执行模型,并提出一种略有变化的版本:在该版本中,将计算程序置于固定状态,而不是线程。例如,在矩阵乘法方面,CUDA和Triton的区别在于:

CUDA计算编程模型

(Scalar Program, Blocked Threads)

Triton编程模型

(Blocked Program, Scalar Threads)

#pragma parallel
for(int m = 0; m < M; m++)
#pragma parallel
for(int n = 0; n < N; n++){float acc = 0;for(int k = 0; k < K; k++)acc += A[m, k] * B[k, n];C[m, n] = acc;
}
#pragma parallel
for(int m = 0; m < M; m += MB)
#pragma parallel
for(int n = 0; n < N; n += NB){float acc[MB, NB] = 0;for(int k = 0; k < K; k += KB)acc +=  A[m:m+MB, k:k+KB]@ B[k:k+KB, n:n+NB];C[m:m+MB, n:n+NB] = acc;
}





该方法的一个重要优势是,它可以采用块式结构架构,从而为编程者提供了更多选择性,并让他们在实现稀疏算法时能获得与存在的DSL语言相比更大的灵活性。同时,编译器还可以将这些语言用于进行数据局部化和并行化优化

挑战¶

我们提出的范式带来的主要挑战是工作调度,即如何对每个程序实例完成的工作进行分区,以便在现代 GPU 上高效执行。为了解决这个问题,Triton编译器大量使用块级数据流分析,这是一种基于目标程序的控制和数据流结构静态调度迭代块的技术。最终的系统实际上运行得非常好:我们的编译器设法自动应用了各种有趣的优化(例如,自动合并、线程摆动、预取、自动矢量化、张量核心感知指令选择、共享内存分配/同步、异步复制调度)。当然,做这一切并非易事;本指南的目的之一是让您了解它是如何工作的

相关工作

在初次看到Triton之后,它可能给人的感觉就是这种新兴DNN上下行网络(DDN)的DSL。本节将首先介绍Triton的目的和性质,并且从两个具有重要影响力的领域——多面体编译语言以及图结构计划语言的角度进行对比。

多面体编译-Polyhedral Compilation

编译器中的多面体模型(polyhedral model)是一种高效的程序优化技术,它将复杂的循环依赖关系映射到高维几何空间,从而在编译阶段实现对计算任务的并行化和局部性优化。通过构建和操作多面体表示能有效地调度指令和数据访问,减少资源争用和缓存未命中德情况,从而提高程序执行的性能
传统的编译器通常依靠介于原始代码和机器语言之间的 “中间表达形式” (如LLVM-IR,这个形式将控制流程信息编码到条件性或非条件性分支中),这种格式是相对低层的。这样一来,就会带来难以实现对输入程序在运行时的执行情况(比如缓存填充问题)进行静态分析、并予以自动优化等方面的问题。因此,triton使用“多边形编译器”[安科尔特,1991]来解决这个问题,该编译器通过采用有可预测控制流程的代码表示方式,实现了对数据流行为的优化。然而,这种策略在目前已经被多个语言和编译器(如Tiramisu[巴格达迪,2021]、Tensor Comprehensions [沃利克,1989]、Diesel[伊兰戈,2018]和MLIR的Affine dialect[拉特纳,2019])采用,但这种方法也存在一些局限性,后文将对此进行详细介绍。

Program Representation

多面体编译是一项广泛的研究领域,本节只是简要介绍了这个话题的基础知识,对于想更加深入地了解此话题相关核心方面内容的读者们,可以参见丰富的线性和整数编程研究文献。

for(int i = 0; i < 3; i++)
for(int j = i; j < 5; j++)A[i][j] = 0;


以上将等式转化成了一个二维平面表示的约束,这些约束的交集对应了二维空间上的一个多面体(polyhedron),同理可得如果是三层循环空间,那就是对应了三维空间上的一个多面体,每个约束条件对应一个二维平面,而在 n 维空间上就是一个超平面了。

多面体编译器是专注于最大化连续程序段的范围,通常称为静态控制模块(Static Control Parts- SCoP),这类程序段中的条件语句和循环限定符都是对周围循环指数以及全局假定变量进行非线性递推计算得出的。triton上文已经给出了一个例子,该程序段将所有条件语句和循环限定符都转换成仿射不等式,然后再与全局变量相乘,这些规则可以用多边形表示;在上例中:

每个点都代表一个多面体语句,也就是一个不涉及控制流转换(如 for、if 和 break)的程序句子,同时只包含了指令中所使用到的索引变量和全局参数函数在内的函数

多面体编译优化关注的是在确保程序执行正确的前提下重组多重循环的结构,实现性能的最优化。
MLIR中Affine方言的定义使用具有多面体特征的循环和条件判断来表示,显示地表示静态控制部分(SCoP:Static Control Part),比如affine.for, affine.if, affine.parallel等,具体可以参见官方文档。在Affine的表达中,使用Dimension和Symbol两类标识符,二者在MLIR语法中均为index类型,同时MLIR也对这两类表示进行约束有助于提升分析和转换能力。从表示形式上看,Dimension以圆括号来声明,Symbol用方括号声明,Dimension即字面意思表示仿射对象的维度信息,比如映射,集合或者具体的loop循环以及一个tensor,Symbol表示的是多面体中的参数,在编译阶段是未知的。在准线性的分析表达上,Symbol当作常量对待,因此Symbol和Dimension之间可以进行乘加等线性操作,但Dimension之间的操作是非法的。另外,Dimension和symbol都遵从SSA赋值。MLIR的Affine重表达体现在通过具体的映射可以表示出多面体的变换,比如图1中的变基操作,通过affine_map语句就能够体现出来。矩阵计算中常用的关于内存的tiling操作,也可以通过affine_map表示。

优点¶

具有多面体编译的可能性的程序可以进行积极的优化和重构,这些重构实际上就是为了生成计划表(schedules)或迭代子集,并在其基础上完成迭代式转换,以推进程序并行化和数据的空间/时间局部性。这类重构包括对循环结构、异构映射、平面切分、并行计算等完成优化和转换。

多胞形编译器也能自动完成复杂的验证过程,以确保在进行优化时输入代码语义的一致性。需要注意的是,多胞形优化器并不与传统的编译策略冲突。实际上,多胞形优化器通常会作为LLVM流水线中的一个子项目进行开发,以便可以在更传统的编译过程之前执行 [GROSSER 2012]。

总的来说,多面体机器是当前最强大、应用广泛的计算机系统。它已经证明能支持矩阵乘法运算所需要的常规算法变换。而且,与现有 GPU 库相比,具备了类似的密集矩阵乘法性能[ELANGO2018]。此外,它还可以实现完全自动化运算,并不需要程序员提供任何其他规则或提示——只是源码必须符合类 C 语言的格式。

缺点

很遗憾,多边形编译器存在两大重要缺点,这使得其无法完全用于神经网络的代码生成。

首先,在编程语言中实现可能的程序转换集合范围十分广泛且随着编程语言所包含的程序语句数量以及对其进行循环操作的规模而不断增大,而在确定每一个转换是否合法时也要解决复杂的实数线性规划问题,从而使得这种编译方式计算成本昂贵。更糟糕的还有,在此方法中不仅要考虑到硬件特性(张量核心的数量、多路传输单元 (multiprocessing modules) 数量)以及语言特征(例如输入图像的形状),从而使得这种编译方式还要进行繁重的自动调整过程 [SATO2019]。

其次,这种多面体框架并不十分适用于广泛的情形; 具有 SCop 结构的神经网络通常较为常见[吉尔巴尔 2006],但其需要计算迭代索引时,必须使用由索引函数组成的可交换插值关系,而这种形式通常只在密集和相对稳定的计算中才会发生。因此,为了将该方法应用于近年来越来越重要的频谱迭代网络,triton还需要克服这种框架在稀疏或结构稠密网络上使用时所面临的困难。

相比之下,本论文提出的阻断程序表达方法在排除范围和优化效率上更为自由,并能以标准数据流分析方式实现近乎最大性能。

调度语言-Scheduling Languages¶

词义分离原则(DIJKSTRA,1982)是计算机科学界很有名的设计方法:程序应该将其核心的意图通过模块化、形式化、层次化的方式分解成不同的部分,这样能保证算法语义与实现细节之间的相互独立。 Halide 和 TVM 等系统正是在这一设计思想基础上推进了一步,他们将叙述语言中的编程方法应用于图灵机理,并以此来实现算法定义(第 1-7 行)与实现(第8-16行)之间的逻辑分割。如下所示,通过这种方式,将算法语义和实现细节分开的优点是在其他计算机程序中特别明显,可以看到定义部分(Line 1-7)与实现部分(Line 8-16)完全隔离,这意味着两者都可以单独进行优化、重构和分发。

// algorithm
Var x("x"), y("y");
Func matmul("matmul");
RDom k(0, matrix_size);
RVar ki;
matmul(x, y) = 0.0f;
matmul(x, y) += A(k, y) * B(x, k);
// schedule
Var xi("xi"), xo("xo"), yo("yo"), yi("yo"), yii("yii"), xii("xii");
matmul.vectorize(x, 8);
matmul.update(0).split(x, x, xi, block_size).split(xi, xi, xii, 8).split(y, y, yi, block_size).split(yi, yi, yii, 4).split(k, k, ki, block_size).reorder(xii, yii, xi, ki, yi, k, x, y).parallel(y).vectorize(xii).unroll(xi).unroll(yii);

但是这种方法可能会导致的代码并不具有完全的移植性,因为在部分情况下,调度器可以对硬件特性(例如SPMD执行模型)和指令集(如:向量乘积和加法运算)的选取而有所限制。这个问题可通过引入自动调度功能来降低其影响[MULLAPUDI 2016]。

优势

这种方法的主要优点是能让程序员只编写一次算法,而不必担心性能优化。在此过程中,他们可以根据自己的需求手动指定算法的优化,这些优化通常是由立方体编译器无法实现的,而必须使用静态数据流分析才能完成。

毫无疑问,调度语言是神经网络代码生成最流行的方法之一。为此,最流行的系统可能是 TVM,它在各种平台上提供良好的性能以及内置的自动调度机制。

缺点

这种开发简便性的提高,也会造成一定代价。首先,运用该模型所建构的现有系统在兼容现今处理器(如 V100/A100 等,并使用相同瓦片大小)时通常会显得明显较慢;这种情况下,Triton 则会比该系统更加高效。我认为,这不是语言编程的基本问题——也就是说可以通过一些简单操作解决问题——但采用这种方法构建系统会使开发过程更加艰难。更重要的是,现有编程语言所生成的并行程序通常不能使涵盖卷积操作的冗余迭代变量的边界和增量值取决于周围迭代指针值,否则将会对可能的并行计划造成重大限制——甚至使系统完全失效。这是在处理无序操作时引入浮点数滞后问题的一种有害方式,因为卷积空间可能会出现不规则的情况。

for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)float acc = 0;for(int k = 0; k < K[i]; k++)acc += A[i][col[i, k]] * B[k][j]C[i][j] = acc;



与此相反,triton所倡导的并行程序结构具有基于块的特性,可以实现采用并行迭代的程序编写方式,而且这种编写方法还能使开发者在自动分配进程和数据调整下功夫。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/33935.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android | 性能优化 之 TraceView工具的使用

上代码&#xff01; 先加权限&#xff1a; <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name"android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 选择跟踪范围,在开始追踪和结束…

景联文科技构建高质量多轮对话数据库,赋能AI交互新飞跃

近年来&#xff0c;大语言模型的发展极大推动了自然语言处理领域的进步&#xff0c;大语言模型正引领智能对话领域进入一个全新时代&#xff0c;不仅提升了对话体验的自然度和效率&#xff0c;也为探索更加人性化、智能化的交互方式开辟了道路。 景联文科技作为大语言模型数据服…

node.js 离线实时语音识别

前言 在node.js实现语音实时转文字。获取麦克风实时语音转文字。 下面是用vosk的效果。注意踩坑要及时评论哦&#xff0c;坑还是挺多的。 在探索后发现本地模型对设备还是有一定要求的&#xff0c;最总无奈采用百度语音识别的方案。 探索结果分享给大家&#xff0c;希望能在项…

AI视频教程下载-定制GPT:使用您的数据创建一个定制聊天GPT

Custom GPTs_ Create a Custom ChatGPT with Your Data 构建一个定制的GPT&#xff0c;与您自己的数据进行聊天。添加文档&#xff0c;生成图像&#xff0c;并集成API和Zapier。 这门全面的Udemy课程专为那些渴望学习如何创建自己定制版ChatGPT的人设计&#xff0c;以满足他们…

jstack的火焰图使用说明

1、jstack的官方文档说明 How to use Flame Graph? - Fast thread 2、jstack的文件分析网站&#xff0c;可以关注cpu消耗比较高的线程和火焰图 GC log analysis error

基于springboot+Vue高校宿舍管理系统的设计与实现【附源码】

本科毕业设计&#xff08;论文&#xff09; 基于springbootVue高校宿舍管理系统的设计与实现 目录 摘要 2 第一章 绪论 2 1.1 开发背景 2 1.2 开发意义 2 第二章 系统分析 3 2.1 系统的需求分析 3 2.2 系统开发设计思想 3 2.3系统开发步骤 3 2.4 系统的主要技术 4 2.4.1 B/S系…

JavaWeb系列八: WEB 开发通信协议(HTTP协议)

HTTP协议 官方文档什么是HTTP协议快速入门页面请求的一个问题(分析)http请求包分析(get)http请求包分析(post)GET请求 POST请求分别有哪些http响应包分析常用的状态码说明状态码200状态码404状态码500状态码302状态码304 MIME类型MIME介绍常见的 MIME 类型 官方文档 HTTP常见请…

七个值得收藏的资源网站,一定要码住~

1、壁纸网站&#xff1a;wallhere https://wallhere.com/ 这是一个免费的高清壁纸网站&#xff0c;各种类型的壁纸资源都有&#xff0c;高清无水印&#xff0c;每款壁纸都能下载到不同的尺寸&#xff0c;适应电脑、安卓手机和苹果手机的屏幕 2、电子书网站&#xff1a;熊猫搜…

java编写的界面可以调用python吗

如何使用Java调用Python程序 本文为大家介绍如何java调用python方法&#xff0c;供大家参考。 实际工程项目中可能会用到Java和python两种语言结合进行&#xff0c;这样就会涉及到一个问题&#xff0c;就是怎么用Java程序来调用已经写好的python脚本呢&#xff0c;一共有三种…

【源码+文档+调试讲解】牙科就诊管理系统

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本牙科就诊管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

学法减分题库最新版,分享几个简单试用的学习和搜题工具 #微信#经验分享#知识分享

告别繁琐的查询步骤&#xff0c;用我们的拍照搜题功能&#xff0c;只需几秒钟&#xff0c;答案就出现在你眼前&#xff0c;让学习变得更加高效便捷。 1.减分侠 这是个辅助学分减分的公众号 根据新的学法减分考试大纲&#xff0c;涵盖小车、客车、货车、摩托车&#xff0c;各…

【AI落地应用实战】如何高效检索与阅读论文——302.AI学术论文工具评测

一、引言 作为一名学术领域的探索者&#xff0c;我们都知道&#xff0c;检索和阅读论文是我们获取知识、启发思考、验证假设的基石&#xff0c;也是日常学习中必不可少的基本功之一。然而在浩瀚的学术海洋中&#xff0c;如何快速、准确地找到我们需要的论文&#xff0c;就像是…

史上最全涵盖在线离线nginx安装手册(含国产信创环境下麒麟V10)

下载安装包略 下载地址&#xff1a;http://nginx.org/download/nginx-版本.tar.gz 配合下载资源食用更佳 https://download.csdn.net/download/ProGram_BlackCat/89480431 安装 tar -zxvf nginx-1.16.1.tar.gz && cd nginx-1.16.1# 创建安装目录(默认路径↓) mkdir /u…

摩柏BI,轻松实现word报告自动更新

|| 导语 告别手工&#xff01;在数字化办公的今天&#xff0c;高效、准确的数据处理能力已经成为职场人士必备的技能之一。尤其是对于财务分析师、市场研究员和管理人员&#xff0c;他们需要处理的报告不仅数量庞大&#xff0c;而且对数据的准确性和实时性要求极高。传统WORD报…

指针(一)

指针基础 在C中&#xff0c;指针是至关重要的组成部分。它是C语言最强大的功能之一&#xff0c;也是最棘手的功能之一。 指针具有强大的能力&#xff0c;其本质是协助程序员完成内存的直接操纵。 指针&#xff1a;特定类型数据在内存中的存储地址&#xff0c;即内存地址。 …

计算机网络课程实训:局域网方案设计与实现(基于ensp)

文章目录 前言基本要求操作分公司1分公司2总部核心交换机配置实现内部服务器的搭建acl_deny部分用户与服务器出口出口防火墙配置 前言 本篇文章是小编实训部分内容&#xff0c;内容可能会有错误&#xff0c;另外ensp对电脑兼容性及其挑剔&#xff0c;在使用之前一定要安装好。…

大模型日报|8 篇必读的大模型论文

大家好&#xff0c;今日必读的大模型论文来啦&#xff01; 1.M2Lingual&#xff1a;在大语言模型中加强多语言、多轮次的指令对齐 指令微调对于大语言模型&#xff08;LLM&#xff09;按照指令进行对齐至关重要。最近提出了许多有效的 IFT 数据集&#xff0c;但大多数数据集都…

七天速通javaSE:第一天 入门:Hello,Word与程序运行机制

文章目录 前言一、Hello&#xff0c;Word&#xff01;1.新建一个文件夹存放代码2.新建一个.java文件3.编写代码 二、编译与运行1.在控制台编译java文件2.运行class文件 三、java程序运行机制1.高级语言的分类1.1 编译型语言1.2 解释型语言 2.程序运行机制 四、IDEA五、代码规范…

lambdastreammaven

1.Lambda &#xff08;1&#xff09;Java 8 Lambda 表达式 在 Java 8 以前&#xff0c;若我们想要把某些功能传递给某个方法&#xff0c;总要去写内部类 或匿名内部类类。代码示例&#xff1a; list.sort(new Comparator<User>() { Override public int compare(User …

Linux显示服务器Wayland切换到X11

1、临时切换 &#xff1a; 注销当前用户账户&#xff0c;返回到登录屏幕。 在登录屏幕上&#xff0c;选择您要登录的用户账户。 在输入密码之前&#xff0c;在登录屏幕的右下角可能有一个齿轮图标&#xff0c;点击它以展开更多选项。 在选项中选择“Ubuntu on Xorg”或“Ubu…