OpenAI的Triton能替代Nvidia的CUDA吗

先说我的观点,我觉得可以,但是应该不是现在。

然后得补个概念,啥是Triton

OpenAI的Triton 是一种专为高效编写深度学习运算而设计的编程语言和编译器。它旨在简化用户编写针对现代GPU(尤其是NVIDIA GPU)的自定义运算代码的过程,从而提升性能和效率。CUDA Toolkit 则是NVIDIA提供的一个全面的GPU计算平台和编程模型,包含了编译器、库、工具和文档,支持开发高性能的GPU应用程序。

Triton与CUDA Toolkit的关系
  1. 依赖关系:

    • CUDA Toolkit 是Triton运行的基础。Triton依赖于CUDA Toolkit中的编译器(如nvcc)、库(如cuBLAS、cuDNN)以及其他开发工具来生成和执行高效的GPU代码。(需要强调现阶段,其实cuBLAS就可以不太用了,比如我自己写矩阵乘,一会的demo就是)

    • Triton 使用CUDA编译器将其代码转换为高效的GPU内核,因此需要CUDA Toolkit的支持才能正常工作。(需要强调现阶段)

  2. 功能定位:

    • CUDA Toolkit 提供了底层的GPU编程接口和优化工具,适用于各种GPU计算任务。

    • Triton 则专注于简化和优化深度学习相关的GPU运算,提供更高层次的抽象,使得编写高性能GPU代码更为便捷。

那我都有CUDA了,这不又造轮子吗?

不是的。

第一:虽然说现阶段的Triton比较高维,脱胎在CUDA之上(其实现在已经很少设计cuda toolkit了,主要是driver和一些特定函数,以后就只会是driver),最终是要跨平台的。

第二:我好多算子可以在triton上写,高维,编辑便捷,同时对下的调用要远好于cuda,好多都可以全自动,比如显存和读取矩阵的方式等等

9月17号Triton大会上,那可是能来站台都来站台了,就不说什么各种chip公司,高通,intel,AMD,连NV自己都来了

图片

图片

这人就是OpenAI 的 Philippe Tillet,Triton 的最hardcore 的contributor

图片

PT也直接拿出大家对Triton的吐槽来说事,其实这也是现在着急要做的,因为现在还没那么通用,离它最重要的工作还差得远。

稍微解释一下主要分支和不同后端的编译流程:

AST:

抽象语法树(Abstract Syntax Tree)。

这是编译器将源代码解析成的树状结构,表示语法结构。

Triton-IR:

Triton 中间表示(Intermediate Representation)。

这是Triton编译器内部使用的一种中间表示,用于将代码转换为 GPU 代码之前的步骤。

TritonGPU-IR:

Triton GPU 中间表示。

专门针对 GPU 的中间表示,用于进一步优化和转换为具体的 GPU 指令。

LLVM-IR:

LLVM 中间表示。

底层系统中间表示,能够被转换为具体目标机器代码。LLVM 就不解释了,看懂的不用解释,看不懂的也不需要解释。。。

一年前 Triton 在代码库设计上的一些缺陷,主要体现在代码的可扩展性和可维护性方面。通过每个步骤(AST → Triton-IR → TritonGPU-IR → LLVM-IR)展示了当前的编译流程如何反映在不同分支上的重复,而这种重复正是导致代码库难以扩展和维护的原因。这张图强调了需要一种更好的方法来简化和统一编译流程,使得代码库更具扩展性和可维护性。所以下一年,Triton 需要在软件结构上加强了“sharing a core infrastructure”的设计

图片

(别忘了初心啊)

然后Pytorch社区更是高举大旗支持Triton(它俩毕竟有共同的利益,就是跨平台的无缝化)

Torch2.4以后,在CUDA free的情况下,在推理上已经能达到CUDA的百分之80左右,以下是上一年的数据

图片

图片

大会上最新的数据,Triton在H100,也就是Hopper架构上,已经干了CuBLAS了(其实我的demo也在局部能生出一些)

图片

绿色是cuBLAS,黄色是上一年的Triton战绩,蓝色是今年的。

我现在做不了cuda free,因为我环境是A10的(玩不到AMD的卡,我只有MI25,支持不了Triton),但是我的矩阵乘的函数是拿Triton写的,一会看个意思就行

 
import torch  # 导入 PyTorch 库,用于生成张量和调用矩阵乘法函数
import triton  # 导入 Triton 库,用于编写和运行自定义 GPU 内核
import triton.language as tl  # 导入 Triton 语言模块,用于编写 Triton 内核# 判断当前是否使用 CUDA
def is_cuda():return triton.runtime.driver.active.get_current_target().backend == "cuda"# 定义 CUDA 平台的自动调优配置,拿triton来干这事
def get_cuda_autotune_config():return [triton.Config({'BLOCK_SIZE_M': 128, 'BLOCK_SIZE_N': 256, 'BLOCK_SIZE_K': 64, 'GROUP_SIZE_M': 8}, num_stages=3, num_warps=8),triton.Config({'BLOCK_SIZE_M': 64, 'BLOCK_SIZE_N': 256, 'BLOCK_SIZE_K': 32, 'GROUP_SIZE_M': 8}, num_stages=4, num_warps=4),# 如果想加更多配置,就在这triton.Config]# 获取 CUDA 的自动调优配置
def get_autotune_config():return get_cuda_autotune_config()# 设置参考库,CUDA 平台使用 cuBLAS
ref_lib = 'cuBLAS'# 配置基准测试,我是A10就拿FP16就完了
configs = [triton.testing.Benchmark(x_names=["M", "N", "K"],  x_vals=[128 * i for i in range(2, 33)],  line_arg="provider",  line_vals=[ref_lib.lower(), "triton"], line_names=[ref_lib, "Triton"],  styles=[("green", "-"), ("blue", "-")], ylabel="TFLOPS",  plot_name="matmul-performance-fp16", args={}, )
]# 定义 Triton 的矩阵乘法内核
@triton.jit
def matmul_kernel(a_ptr, b_ptr, c_ptr, M, N, K, stride_am, stride_ak, stride_bk, stride_bn, stride_cm, stride_cn,BLOCK_SIZE_M: tl.constexpr, BLOCK_SIZE_N: tl.constexpr, BLOCK_SIZE_K: tl.constexpr, GROUP_SIZE_M: tl.constexpr):pid = tl.program_id(axis=0)  # 获取程序 IDnum_pid_m = tl.cdiv(M, BLOCK_SIZE_M)  # 沿 M 轴的线程块数量num_pid_n = tl.cdiv(N, BLOCK_SIZE_N)  # 沿 N 轴的线程块数量num_pid_in_group = GROUP_SIZE_M * num_pid_n  # 每组线程块的数量group_id = pid // num_pid_in_group  # 计算当前块所属的组 IDfirst_pid_m = group_id * GROUP_SIZE_M  # 当前组中第一个线程块的 M 轴 IDgroup_size_m = min(num_pid_m - first_pid_m, GROUP_SIZE_M)  # 当前组的实际大小pid_m = first_pid_m + ((pid % num_pid_in_group) % group_size_m)  # 当前线程块在 M 轴的 IDpid_n = (pid % num_pid_in_group) // group_size_m  # 当前线程块在 N 轴的 IDoffs_am = (pid_m * BLOCK_SIZE_M + tl.arange(0, BLOCK_SIZE_M)) % M  # A 矩阵的行偏移offs_bn = (pid_n * BLOCK_SIZE_N + tl.arange(0, BLOCK_SIZE_N)) % N  # B 矩阵的列偏移offs_k = tl.arange(0, BLOCK_SIZE_K)  # K 维度的偏移a_ptrs = a_ptr + (offs_am[:, None] * stride_am + offs_k[None, :] * stride_ak)  # A 矩阵块的指针b_ptrs = b_ptr + (offs_k[:, None] * stride_bk + offs_bn[None, :] * stride_bn)  # B 矩阵块的指针accumulator = tl.zeros((BLOCK_SIZE_M, BLOCK_SIZE_N), dtype=tl.float32)  # 初始化累加器for k in range(0, tl.cdiv(K, BLOCK_SIZE_K)):  # 遍历 K 维度的块a = tl.load(a_ptrs, mask=offs_k[None, :] < K - k * BLOCK_SIZE_K, other=0.0)  # 加载 A 块b = tl.load(b_ptrs, mask=offs_k[:, None] < K - k * BLOCK_SIZE_K, other=0.0)  # 加载 B 块accumulator = tl.dot(a, b, accumulator)  # 计算并累加结果a_ptrs += BLOCK_SIZE_K * stride_ak  # 更新 A 块指针b_ptrs += BLOCK_SIZE_K * stride_bk  # 更新 B 块指针c = accumulator.to(tl.float16)  # 将结果转为 float16offs_cm = pid_m * BLOCK_SIZE_M + tl.arange(0, BLOCK_SIZE_M)  # C 矩阵的行偏移offs_cn = pid_n * BLOCK_SIZE_N + tl.arange(0, BLOCK_SIZE_N)  # C 矩阵的列偏移c_ptrs = c_ptr + stride_cm * offs_cm[:, None] + stride_cn * offs_cn[None, :]  # C 矩阵块的指针c_mask = (offs_cm[:, None] < M) & (offs_cn[None, :] < N)  # 计算 C 块的有效掩码tl.store(c_ptrs, c, mask=c_mask)  # 存储结果到 C 块# 定义 matmul 函数,用于调用 Triton 内核
def matmul(a, b):M, K = a.shape  # 获取 A 矩阵的维度K, N = b.shape  # 获取 B 矩阵的维度c = torch.empty((M, N), device=a.device, dtype=a.dtype)  # 创建空的 C 矩阵stride_am, stride_ak = a.stride()  # 获取 A 矩阵的步长stride_bk, stride_bn = b.stride()  # 获取 B 矩阵的步长stride_cm, stride_cn = c.stride()  # 获取 C 矩阵的步长grid = lambda META: (triton.cdiv(M, META['BLOCK_SIZE_M']) * triton.cdiv(N, META['BLOCK_SIZE_N']),)  # 定义网格大小matmul_kernel[grid](a, b, c, M, N, K, stride_am, stride_ak, stride_bk, stride_bn, stride_cm, stride_cn,BLOCK_SIZE_M=128, BLOCK_SIZE_N=128, BLOCK_SIZE_K=64, GROUP_SIZE_M=8)  # 调用内核return c# 基准测试函数,使用装饰器添加自动性能报告功能
@triton.testing.perf_report(configs)
def benchmark(M, N, K, provider):a = torch.randn((M, K), device='cuda', dtype=torch.float16)  # 生成随机 A 矩阵b = torch.randn((K, N), device='cuda', dtype=torch.float16)  # 生成随机 B 矩阵quantiles = [0.5, 0.2, 0.8]  # 性能衡量的分位数if provider == ref_lib.lower():# 使用参考库进行基准测试,这个是调torch+cuBLASms, min_ms, max_ms = triton.testing.do_bench(lambda: torch.matmul(a, b), quantiles=quantiles)if provider == 'triton':# 使用 Triton 进行基准测试,这个就是调的triton写的矩阵乘方法ms, min_ms, max_ms = triton.testing.do_bench(lambda: matmul(a, b), quantiles=quantiles)perf = lambda ms: 2 * M * N * K * 1e-12 / (ms * 1e-3)  # 计算性能(TFLOPS)return perf(ms), perf(max_ms), perf(min_ms)# 运行基准测试并显示结果
benchmark.run(show_plots=True, print_data=True)

这个代码的目的是使用 Triton 和 cuBLAS 在 NVIDIA A10 GPU 上进行矩阵乘法的性能基准测试,比较两者的计算效率。:总体流程和概念 1. 导入库:导入需要的 PyTorch (他就是直接调cuda的cuBLAS了)和 Triton 库。

2. 定义配置和判定函数:  - 为 CUDA 平台定义自动调优配置。  - 确定参考库为 cuBLAS。

3. 配置基准测试:设置基准测试参数,定义不同库(cuBLAS 和 Triton)的测试配置。

4. 定义矩阵乘法内核:编写 Triton 的矩阵乘法内核,通过自动调优,优化内核性能。

5. 定义矩阵乘法函数:调用 Triton 定义的内核实现矩阵乘法。

6. 定义基准测试函数:通过对比 cuBLAS 和 Triton 的矩阵乘法性能,测量各自的执行时间和性能(TFLOPS)。这样可以整体地对比 Triton 和 cuBLAS 矩阵乘法性能

主要PK的就是这块

if provider == ref_lib.lower():        # 使用参考库进行基准测试,这个是调torch+cuBLAS        ms, min_ms, max_ms = triton.testing.do_bench(lambda: torch.matmul(a, b), quantiles=quantiles)    if provider == 'triton':        # 使用 Triton 进行基准测试,这个就是调的triton写的矩阵乘方法        ms, min_ms, max_ms = triton.testing.do_bench(lambda: matmul(a, b), quantiles=quantiles)

深度学习玩啥啊?说来说去,要涉及性能的,不就是玩矩阵乘么(当然激活函数啥也算,triton也一样都行,我在这就展示矩阵乘就可以了)

显存占的不多,我的矩阵M*K和K*N也没多大,但是GPU的tflops打上去了,虽然也打不满,毕竟维度太小,看个意思。

图片

图片

  • 低维矩阵(M < 1000):

    • Triton 和 cuBLAS 性能差不多,二者的线条几乎重合。

  • 中间区域(1000 < M < 3000):

    • 在这一范围内,Triton 的蓝线稍高于 cuBLAS 的绿线,说明 Triton 的性能略高于 cuBLAS。

    • 特别是在 M 达到 2000 左右时,Triton 的性能达到峰值,接近 100 TFLOPS。

  • 高维矩阵(M > 3000):

    • 在这个范围内,两者的性能开始趋于稳定,Triton 和 cuBLAS 的性能非常接近。

    • 性能的微小波动可能是由于硬件和算法的微小差异导致的。

在A10这种破烂卡上面,都能咬住CUDA在矩阵乘上面的实力,我还是挺震惊的,之前那个Hopper架构上今年已经超过CUDA了,应该所言非虚,那剩下的,我们就指望着Triton能在非NV的卡上,能跑出同等级NV卡的能力,哪怕差点不多,那个时候可能真的就要变天了,因为天下苦NV久矣,不是苦它的sm数量和hbm速度,这玩意都能弄,主要是编算子太难了,又费劲,又少,OpenAI的Triton之所以以后一定能行,就因为它是OpenAI的项目,你觉得它缺算子么?

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

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

相关文章

【黑马Redis原理篇】Redis数据结构

视频来源&#xff1a;原理篇[2,15] 文章目录 1.动态字符串SDS1.1 内部结构&#xff1a; 2.IntSet3.Dict3.1 dict的内部结构3.2 dict的扩容 4.ziplist压缩列表5.QuickList6.SkipList跳表7.RedisObject对象8.Redis的五种数据结构8.1 String8.2 List8.3 Set8.4 Zset 有序集合8.5 …

SpringBoot 创建多模块项目 项目分模块 项目简化 打包发布

介绍 在 Spring Boot 中&#xff0c;创建多模块项目可以帮助我们将项目拆分成多个相对独立、可重用的模块&#xff0c;从而使代码结构更清晰&#xff0c;便于管理和维护。通常&#xff0c;这样的做法可以提高开发效率&#xff0c;并且更易于进行版本控制和分布式部署。 项目结…

MySQL 数据库之表操作

1. 创建表 CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) [character set 字符集 collate 校验规则 engine 存储引擎];field 表示列名datatype 表示列的类型character set 字符集&#xff0c;如果没有指定字符集&#xff0c;则以所在数据库…

【R78/G15 开发板测评】串口打印 DHT11 温湿度传感器、DS18B20 温度传感器数据,LabVIEW 上位机绘制演化曲线

【R78/G15 开发板测评】串口打印 DHT11 温湿度传感器、DS18B20 温度传感器数据&#xff0c;LabVIEW 上位机绘制演化曲线 主要介绍了 R78/G15 开发板基于 Arduino IDE 环境串口打印温湿度传感器 DHT11 和温度传感器 DS18B20 传感器的数据&#xff0c;并通过LabVIEW上位机绘制演…

Chromium Mojo(IPC)进程通信演示 c++(2)

122版本自带的mojom通信例子associated-interface 仅供学习参考&#xff1a; codelabs\mojo_examples\02-associated-interface-freezing 一、目录结构如图&#xff1a; 二、interface.mojom接口 1、codelabs\mojo_examples\mojom\interface.mojom // Copyright 2023 The C…

「Mac畅玩鸿蒙与硬件32」UI互动应用篇9 - 番茄钟倒计时应用

本篇将带你实现一个番茄钟倒计时应用&#xff0c;用户可以设置专注时间和休息时间的时长&#xff0c;点击“开始专注”或“开始休息”按钮启动计时&#xff0c;应用会在倒计时结束时进行提醒。番茄钟应用对于管理时间、提升工作效率非常有帮助&#xff0c;并且还会加入猫咪图片…

u盘怎么重装电脑系统_u盘重装电脑系统步骤和详细教程【新手宝典】

u盘怎么重装电脑系统&#xff1f;一个u盘怎么重装电脑系统呢&#xff0c;需要将u盘制作成u盘启动盘pe&#xff0c;然后通过U盘启动盘进入pe进行安装系统&#xff0c;下面小编就教大家u盘重装电脑系统步骤和详细教程。 u盘启动是什么意思&#xff1f; U盘启动盘是一种具有特殊功…

Typora导出pdf手动分页和设置字体样式

手动分页 <div style"page-break-after: always;"></div>鼠标点击代码才会显示&#xff0c;不点击会隐藏。导出pdf时&#xff0c;该位置会分页 设置字体大小、加粗、居中、空格 <p style"font-size:30px; font-weight: bold; text-align: cen…

简简单单的UDP

前言 上一篇了解了TCP的三次握手过程&#xff0c;目的、以及如何保证可靠性、序列号与ACK的作用&#xff0c;最后离开的时候四次挥手的内容&#xff0c;这还只是TCP内容中的冰山一角&#xff0c;是不是觉得TCP这个协议非常复杂&#xff0c;这一篇我们来了解下传输层另外一个协…

淘宝/天猫按图搜索商品:taobao.item_search_img API的奇幻之旅

在这个看脸的时代&#xff0c;我们不仅对人要看颜值&#xff0c;连买东西都要“看脸”了。没错&#xff0c;我说的就是淘宝/天猫的按图搜索商品功能——taobao.item_search_img API。这个功能就像是电商平台的“人脸识别”&#xff0c;只不过它认的是商品的颜值。下面&#xff…

软件工程 软考

开发大型软件系统适用螺旋模型或者RUP模型 螺旋模型强调了风险分析&#xff0c;特别适用于庞大而复杂的、高风险的管理信息系统的开发。喷泉模型是一种以用户需求为动力&#xff0c;以对象为为驱动的模型&#xff0c;主要用于描述面向对象的软件开发过程。该模型的各个阶段没有…

STM32F405RGT6单片机原理图、PCB免费分享

大学时机创比赛时画的板子&#xff0c;比到一半因为疫情回家&#xff0c;无后续&#xff0c;&#xff0c;&#xff0c;已打板验证过&#xff0c;使用stm32f405rgt6做主控 下载文件资源如下 原理图文件 pcb文件 外壳模型文件 stm32f405例程 功能 以下功能全部验证通过 4路…

写一个记录函数执行时间的装饰器

装饰器&#xff0c;这可是Python开发中绕不开的经典话题&#xff0c;不论你是写代码的老手&#xff0c;还是刚入行的萌新&#xff0c;都得和它打上几轮交道。而记录函数执行时间这个功能&#xff0c;更是装饰器中的“常客”。 今天我就带大家来全面解锁一下这块儿的知识&#…

Python 桌面应用开发:使用 Tkinter 创建 GUI 应用程序

Python 桌面应用开发&#xff1a;使用 Tkinter 创建 GUI 应用程序 引言 随着计算机技术的飞速发展&#xff0c;桌面应用程序依然在许多领域中发挥着重要作用。Python 作为一种强大的编程语言&#xff0c;提供了多种工具和库来创建桌面应用程序。其中&#xff0c;Tkinter 是 P…

vue3入门知识(一)

vue3简介 性能的提升 打包大小减少41%初次渲染快55%&#xff0c;更新渲染快133%内存减少54% 源码的升级 使用Proxy代替defineProperty实现响应式重写虚拟DOM的实现和Tree-Shaking 新的特性 1. Composition API&#xff08;组合API&#xff09; setupref与reactivecomput…

AI与就业:技术革命下的职业转型与挑战

内容概要 在当今时代&#xff0c;人工智能的迅猛发展正在深刻影响着我们的就业市场。这一技术革命不仅让我们看到了未来的职业转型&#xff0c;还引发了对于新兴技能需求的深思。随着AI技术的普及&#xff0c;许多传统行业面临着巨大的变革压力&#xff0c;同时也为新兴领域创…

小白初入Android_studio所遇到的坑以及怎么解决

1. 安装Android_studio 参考&#xff1a;Android Studio 安装配置教程 - Windows(详细版)-CSDN博客 Android Studio超级详细讲解下载、安装配置教程&#xff08;建议收藏&#xff09;_androidstudio-CSDN博客 想下旧版本的android_studio的地址&#xff08;仅供参考&#xf…

Uubntu下的Boost库安装及使用

一、Boost库介绍 Boost库是为C语言标准库提供扩展的一些C程序库的总称。 Boost库由Boost社区组织开发、维护。其目的是为C程序员提供免费、同行审查的、可移植的程序库。Boost库可以与C标准库共同工作&#xff0c;并且为其提供扩展功能。Boost库使用Boost License来授权使用&…

【王木头】最大似然估计、最大后验估计

目录 一、最大似然估计&#xff08;MLE&#xff09; 二、最大后验估计&#xff08;MAP&#xff09; 三、MLE 和 MAP 的本质区别 四、当先验是均匀分布时&#xff0c;MLE 和 MAP 等价 五、总结 本文理论参考王木头的视频&#xff1a; 贝叶斯解释“L1和L2正则化”&#xff…

「QT」几何数据类 之 QPointF 浮点型点类

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「QT」QT5程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid…