0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Triton编译器的原理和性能

jf_pmFSk4VX 来源:GiantPandaCV 2023-12-16 11:22 次阅读

我们推出了一个新的系列,对PytorchConference2023 的博客进行中文编译,会陆续在公众号发表。

Triton是一种用于编写高效自定义深度学习原语的语言和编译器。Triton的目的是提供一个开源环境,以比CUDA更高的生产力编写快速代码,但也比其他现有DSL具有更大的灵活性。Triton已被采用为Torch inductor的基本组件,以合成针对GPU的高效内核。与传统库使用相比,这具有多种优势。它允许创建各种各样的融合,它可以独立调整,并且它的内存占用更小。本次演讲将介绍Triton编译器,并描述使其能够以最少的用户努力生成闪电般快速内核的过程。

全文

今天我要和大家谈谈的是Triton。那么,我将要讨论的大致内容是Triton是什么?我们为什么要创建这个工具?它可以用来做什么?然后,我将讨论如何将其集成在ML编译器堆栈中。最后,我将简要介绍其背后的原理以及编译器是如何简化管理的。

Triton是一个Python DSL(领域特定语言),旨在用于编写机器学习内核。 最初,它严格用于GPU内核,但慢慢地扩展以支持用于机器学习的任何硬件,包括CPUASIC等。Triton的目标是让那些没有GPU经验的研究人员能够编写高性能代码。如果你看到幻灯片底部的图表,那真的是Triton想要达到的地方。通过少量的开发工作,你可以非常接近峰值性能。

95e409ca-9bb7-11ee-8b88-92fbcf53809c.jpg

简而言之,Triton是一个帮助研究人员轻松编写高性能机器学习内核的工具,无论他们是否有GPU经验。

当然,总是会有像CUDA或汇编语言这样的其他语言,它们能让你获得同样或更高的性能,但通常你需要对硬件有更多的了解,并花费更多的时间。为什么我们需要这种新的语言呢?如果你看看现有的选择,例如在不同的硬件上编程机器学习,有PyTorch这样的工具,它允许你轻松地将不同类型的操作映射到硬件上,并且非常容易从中获得高性能。

但问题在于你对它的控制非常有限。如果现有的操作集中没有你需要的东西,你就只能束手无策,唯一的解决办法是走向另一个极端,例如编写CUDA或编写PTX,甚至直接编写汇编代码。但问题在于,要编写这些语言,你需要真正成为硬件方面的专家,并且用这些语言编写高效的内核可能非常棘手 。所以Triton实际上是尝试在这里找到一个中间地带,它允许用户编写高效的内核,并有大量的控制权,但又不必关心那些微小的细节。

是的,硬件的细节以及如何在特定硬件上获得性能。实际上,设计的难点在于找到这个最佳平衡点。Triton的设计方式就是找到这个抽象的平衡点,即你想向用户暴露什么,以及你想让编译器做什么?

95fd4ebc-9bb7-11ee-8b88-92fbcf53809c.jpg

编译器是生产力工具,真的……在这方面,Triton的目标是让编译器为你完成你不想做的工作,但仍然让你能够控制算法、你想要用来进行调整的任何tuning。Triton介于Cuda和Torch之间,因为你仍然可以编写自己的算法,你仍然可以控制自己的类型,你仍然需要决定是否需要以某种类型来保存中间值,你控制所有的精度。你不必关心如何处理共享内存、在目标有张量核时使用张量核、如何很好地处理负载聚合,以便你有良好的内存访问模式。 这些人们在编写GPU内核时经常要考虑的事情。你总是要担心这些问题,或者弄清楚我的中间数据的布局是什么等等。编译器会为你完成这些工作。

让我们来看一个例子。这是一个softmax内核的示例。这是一个工作解决方案的复制品,它是有效的。

#https://github.com/openai/triton/blob/main/python/tutorials/02-fused-softmax.py
@triton.jit
defsoftmax_kernel(output_ptr,input_ptr,input_row_stride,output_row_stride,n_cols,BLOCK_SIZE:tl.constexpr):
#Therowsofthesoftmaxareindependent,soweparallelizeacrossthose
row_idx=tl.program_id(0)
#Thestriderepresentshowmuchweneedtoincreasethepointertoadvance1row
row_start_ptr=input_ptr+row_idx*input_row_stride
#Theblocksizeisthenextpoweroftwogreaterthann_cols,sowecanfiteach
#rowinasingleblock
col_offsets=tl.arange(0,BLOCK_SIZE)
input_ptrs=row_start_ptr+col_offsets
#LoadtherowintoSRAM,usingamasksinceBLOCK_SIZEmaybe>thann_cols
row=tl.load(input_ptrs,mask=col_offsets< n_cols, other=-float('inf'))
    # Subtract maximum for numerical stability
    row_minus_max = row - tl.max(row, axis=0)
    # Note that exponentiation in Triton is fast but approximate (i.e., think __expf in CUDA)
    numerator = tl.exp(row_minus_max)
    denominator = tl.sum(numerator, axis=0)
    softmax_output = numerator / denominator
    # Write back output to DRAM
    output_row_start_ptr = output_ptr + row_idx * output_row_stride
    output_ptrs = output_row_start_ptr + col_offsets
    tl.store(output_ptrs, softmax_output, mask=col_offsets < n_cols)

第一个有趣的事情是这段代码相对较短。如果你用CUDA编写同样的内核,它实际需要更多的努力。我们可以注意到一些有趣的事情。例如,你可以控制如何在计算机上分配工作。多亏了这些编程思想。你可以看到,你仍然可以控制你的内存访问,因为你可以访问指针。你可以基于一些原始指针加载一大块数据。然后编译器将在后台决定将其映射到硬件的最佳方式,以及如何进行聚合,如何处理所有事情,以便这个加载将是有效的,并将分布到你的GPU的不同线程和warp上。但你不必担心这些。在底部,我们可以看到有一个归约操作,通常它会隐式地使用共享内存,但你不必担心它。编译器将确保你为其选择最佳实现,并为你使用共享内存。

之后我将讨论,如何在典型的设备上使用triton,除了内核他还可以集成到完整的graph编译器堆栈中:

960f1f20-9bb7-11ee-8b88-92fbcf53809c.jpg

Triton为你提供了一个非常容易、非常自然的从graph表示直接到实现的lowering过程,并且它实际上允许更简单的graph表示实现,因为你不必一次性生成一个完美的内核。你可以只生成Triton部分,然后Triton编译器将完成繁重的工作,找出如何有效地将其映射到硬件上。

Triton可以被用作的另一个地方是它可以被用作自定义操作语言 。像PyTorch这样的工具,因为如果你陷入困境,而PyTorch中没有实现某些功能,添加自定义操作是你能够完成你想要做的事情的唯一解决方案。

让我们稍微看一下编译器架构。这是一个非常高层次的查看Triton架构的方式。

9629dcca-9bb7-11ee-8b88-92fbcf53809c.jpg

Triton被构建为一个老式编译器,包括前端、中端和后端。这里有趣的部分是这两个块,Triton IR和Triton GPU IR,它们是Triton的中间IR,这里有很多魔法发生。你可以在这里看到的另一件有趣的事情是,Triton IR真的允许你针对不同的硬件进行定位,因为Triton IR本身对于这硬件是完全无关的。如果我们放大这个有趣的部分,即基本上发生在Triton IR和最终的LLVM IR之间的事情,LLVM IR是最终的目标。

963d65b0-9bb7-11ee-8b88-92fbcf53809c.jpg

基本上,编译器首先接收Triton IR,Triton IR与语言本身非常相似。然后,编译器要做的第一件事是为描述张量如何分布到线程上的布局进行关联。这真的是编译器的核心机制,因为基于这些布局,有多种路径可以改变这些布局,并能够生成一些能够有效地映射到硬件上的东西。因此,我们会像进行coalesce一样,尝试选择一个布局,以便加载存储聚合能够高效进行。

如果机器有tensorcore,我们会尝试使用非常适合tensorcore的布局。然后,我们会尝试避免任何布局转换,应用一系列典型的编译器传递,然后在此基础上进行转换,基于分析转到llvm ir。

这是非常高层次的,但这就是编译器的工作原理。嗯,这就是我想告诉你的全部内容。Triton正在完全开源的情况下进行开发,非常欢迎贡献者。我们每个月都会举行社区会议。

Triton IR本身对硬件无关。但是,如果你把一个在目标上运行良好的内核拿过来,你可能需要重新调整它,以便在另一个目标上运行良好。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    3

    文章

    1309

    浏览量

    39846
  • gpu
    gpu
    +关注

    关注

    27

    文章

    4417

    浏览量

    126705
  • Triton
    +关注

    关注

    0

    文章

    16

    浏览量

    6992
  • 编译器
    +关注

    关注

    1

    文章

    1577

    浏览量

    48617
  • 深度学习
    +关注

    关注

    73

    文章

    5237

    浏览量

    119910

原文标题:《PytorchConference2023 翻译系列》6-Triton编译器

文章出处:【微信号:GiantPandaCV,微信公众号:GiantPandaCV】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    几款C语言编译器推荐

    一些刚开始接触C语言编译的网友想下载一款C语言编译器来使用,不过,网络上有不少C语言编译器相关的软件,让人很难抉择。
    发表于 09-05 09:19 9385次阅读

    ICC AVR编译器的安装与使用

    ICCAVR编译器的安装、运行、破解、使用 用ICCAVR编译器产生初始化程序和程序框架
    发表于 07-09 18:06 258次下载

    基于CoSy的编译器开发的研究

    CoSy是ACE公司开发的编译器构造框架[1]。它提供共享工具和引擎来构造编译器编译器开发者只专注于目标机相关代码的开发。CoSy框架生成的编译器具有可扩展性和可移植性。可以根据目
    发表于 08-19 17:49 0次下载
    基于CoSy的<b class='flag-5'>编译器</b>开发的研究

    stm8编译器下载

    stm8编译器下载
    发表于 04-27 17:46 4次下载

    PICC编译器下载

    PICC编译器下载
    发表于 05-25 17:44 168次下载

    编译器是如何工作的_编译器的工作过程详解

    随着计算机的发展,编译器已经发挥着十分重要的作用。本文主要介绍了编译器的种类、编译器的工作原理以及编译器工作的具体操作过程及步骤详解。
    发表于 12-19 12:54 1.5w次阅读

    既然C编译器是C语言写,那么第一个C编译器是怎样来的?

    既然C编译器是C语言写的,那第一个C编译器是怎样来的?
    的头像 发表于 02-25 15:47 2802次阅读

    王垠谈编译器

    由于早期的 Lisp 编译器生成的代码效率普遍低下,成为了 Lisp 失败的主要原因之一。而现在的高性能 Lisp 编译器(比
    的头像 发表于 03-30 10:45 1869次阅读

    交叉编译器安装教程

    交叉编译器中“交叉”的意思就是在一个架构上编译另外一个架构的代码,相当于两种架构“交叉”起来了。Ubuntu 自带的 gcc 编译器是针对 X86 架构的,而我们现在要编译的是 ARM
    的头像 发表于 09-29 09:12 2656次阅读

    编译器的优化选项

    一个程序首先要保证正确性,在保证正确性的基础上,性能也是一个重要的考量。要编写高性能的程序,第一,必须选择合适的算法和数据结构;第二,应该编写编译器能够有效优化以转换成高效可执行代码的源代码,要做到
    的头像 发表于 11-24 15:37 408次阅读
    <b class='flag-5'>编译器</b>的优化选项