首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【连载】OpenAITriton MLIR 第二章 Batch GEMM benchmark

【连载】OpenAITriton MLIR 第二章 Batch GEMM benchmark

作者头像
BBuf
发布于 2023-08-21 13:02:48
发布于 2023-08-21 13:02:48
95700
代码可运行
举报
文章被收录于专栏:GiantPandaCVGiantPandaCV
运行总次数:0
代码可运行

OpenAI/Triton MLIR 第二章: Batch GEMM benchmark

前言

通过前两章对于triton的简单介绍,相信大家已经能够通过从源码来安装triton,同时通过triton提供的language前端写出自己想要的一些计算密集型算子。这章开始,我们通过构建一套比较标准的batch gemm的benchmark,来看看目前这些主流的代码生成工具,高性能模板库,与厂商提供的vendor library的差距。因为只有明确了目前的差距,后期关于针对性的优化才能做到点上。这一章,我将使用一个batch的gemm作为例子,来看看triton目前对其的优化能力。选batch gemm的原因是因为目前的LLM中不可避免会有对应的attention操作,而attention操作中,核心的计算密集型算子就是batch的gemm,如果你能够对batch的gemm有一个很好的优化思路,那么在MLSys中大部分的算子优化类的工作对你来说将不会显得那么无从下手。

通过Triton实现一个batch GEMM算子

在triton的官方tutorial中给出了如何使用triton的language api来实现gemm的算子,在上一章的最后,我也给出了对应的例子以及他通过和调用torch.matmul实现的gemm在3090上的性能比较。最终可以发现,针对某些size的gemm,triton在TFLOPS这个指标层面是能够超过cublas的实现,但是后面我通过nsight system对每个kernel的具体执行时间进行了profiling,发现在torch.matmul或者torch.bmm底层所调用的cuBLAS的kernel并不是对应输入输出datatype以及computetype中最快的那个。所以,这样的比较就显得有些没有意义。不过,没事,这对我们建立起如何优化一个计算密集型算子来说是一个不错的入门。

其实想要通过triton实现一个batch的gemm非常简单,我们只需要将triton中原先例子里的tl.program_id(axis=0),在这个program_id上再添加一个axis来表示batch维度的并行就可以了,然后针对每个数组的变化由单batch到多batch,只用增加一个大小为矩阵size的stride偏置即可,这种实现方式其实也是cuBLAS中cublasGemmStridedBatched命名的得来。具体的代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@triton.jit
def matmul_kernel(
    # Pointers to matrices
    A_ptr, B_ptr, C_ptr,
    # Matrix dimensions
    B, M, N, K,
    # The stride variables represent how much to increase the ptr by when moving by 1
    # element in a particular dimension. E.g. stride_am is how much to increase a_ptr
    # by to get the element one row down (A has M rows)
    stride_ab, stride_am, stride_ak,
    stride_bb, stride_bk, stride_bn,
    stride_cb, stride_cm, stride_cn,
    # Meta-parameters
    BLOCK_SIZE_M: tl.constexpr, BLOCK_SIZE_N: tl.constexpr, BLOCK_SIZE_K: tl.constexpr,
    GROUP_SIZE_M: tl.constexpr,
    ACTIVATION: tl.constexpr,
):
    pid = tl.program_id(axis=0)
    offs_b = tl.program_id(axis=1)
    num_pid_m = tl.cdiv(M, BLOCK_SIZE_M)
    num_pid_n = tl.cdiv(N, BLOCK_SIZE_N)
    num_pid_k = tl.cdiv(K, BLOCK_SIZE_K)
    num_pid_in_group = GROUP_SIZE_M * num_pid_n
    group_id = pid // num_pid_in_group
    first_pid_m = group_id * GROUP_SIZE_M
    group_size_m = min(num_pid_m - first_pid_m, GROUP_SIZE_M)
    pid_m = first_pid_m + (pid % group_size_m)
    pid_n = (pid % num_pid_in_group) // group_size_m
    
    offs_m = pid_m * BLOCK_SIZE_M + tl.arange(0, BLOCK_SIZE_M)
    offs_n = pid_n * BLOCK_SIZE_N + tl.arange(0, BLOCK_SIZE_N)
    offs_k = tl.arange(0, BLOCK_SIZE_K)
    
    A_ptr = A_ptr + (offs_b * stride_ab + offs_m[:, None] * stride_am + offs_k[None, :] * stride_ak)
    B_ptr = B_ptr + (offs_b * stride_bb + offs_k[:, None] * stride_bk  + offs_n[None, :] * stride_bn)
    
    # initialize and iteratively update accumulator
    acc = tl.zeros((BLOCK_SIZE_M, BLOCK_SIZE_N), dtype=tl.float32)
    for k in range(0, K, BLOCK_SIZE_K):

        a = tl.load(A_ptr)
        b = tl.load(B_ptr)
        
        acc += tl.dot(a, b)
    
        A_ptr += BLOCK_SIZE_K * stride_ak
        B_ptr += BLOCK_SIZE_K * stride_bk
        
    c = acc.to(tl.float16)
    C_ptr = C_ptr + (offs_b * stride_cb + offs_m[:, None] * stride_cm + offs_n[None, :] * stride_cn)
    c_mask = (offs_b < B) & (offs_m[:, None] < M) & (offs_n[None, :] < N)
    tl.store(C_ptr, c, mask=c_mask)

然后写一个简单的单元测试,确保通过triton写出来的kernel能够和torch.matmul/torch.bmm对上即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
torch.manual_seed(0)
a = torch.randn((4, 512, 512), device='cuda', dtype=torch.float16)
b = torch.randn((4, 512, 512), device='cuda', dtype=torch.float16)
torch_output = torch.bmm(a, b)
triton_output = matmul(a, b, activation=None)
print(f"triton_output={triton_output}")
print(f"torch_output={torch_output}")
if torch.allclose(triton_output, torch_output, atol=1e-2, rtol=0):
    print("✅ Triton and Torch match")
else:
    print("❌ Triton and Torch differ")

其实triton的language语法确实很简单,相比较cuda来说,它能够帮我们快速验证一些idea,同时给出比cublas性能相当的算子。如果你想要用CUDA从0开始实现一个batch GEMM并且调用tensor core,借助shared memory,register files去帮你加速运算或者优化data movement,那么这个过程是非常需要一定的高性能计算和架构的经验,你才可能拿到和cuBLAS的kernel接近的性能。OK,有了triton的具体kernel实现,接下来其实就是要去写一个triton需要被调优的模版,需要triton从你定义的这个比较小的搜索空间中,去得到对应的最优解,从而作为本次batch gemm的最优实现,我在autotuner这块并没有花太大的精力去改进,依旧GEMM例子中的模版拿来作为一个参考,具体代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@triton.autotune(
    configs=[
        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({'BLOCK_SIZE_M': 128, 'BLOCK_SIZE_N': 128, 'BLOCK_SIZE_K': 32, 'GROUP_SIZE_M': 8}, num_stages=4, num_warps=4),
        triton.Config({'BLOCK_SIZE_M': 128, 'BLOCK_SIZE_N': 64, 'BLOCK_SIZE_K': 32, 'GROUP_SIZE_M': 8}, num_stages=4, num_warps=4),
        triton.Config({'BLOCK_SIZE_M': 64, 'BLOCK_SIZE_N': 128, 'BLOCK_SIZE_K': 32, 'GROUP_SIZE_M': 8}, num_stages=4, num_warps=4),
        triton.Config({'BLOCK_SIZE_M': 128, 'BLOCK_SIZE_N': 32, 'BLOCK_SIZE_K': 32, 'GROUP_SIZE_M': 8}, num_stages=4, num_warps=4),
        triton.Config({'BLOCK_SIZE_M': 64, 'BLOCK_SIZE_N': 32, 'BLOCK_SIZE_K': 32, 'GROUP_SIZE_M': 8}, num_stages=5, num_warps=2),
        triton.Config({'BLOCK_SIZE_M': 32, 'BLOCK_SIZE_N': 64, 'BLOCK_SIZE_K': 32, 'GROUP_SIZE_M': 8}, num_stages=5, num_warps=2),
    ],
    key=['M', 'N', 'K'],
)

然后通过调用Triton的do_bench就可以将你写的算子跑起来了,do_bench处在python/triton/testing.py下,其中会对每个kernel进行25次的warm_up和100次iteration,最后会根据你设置的分位数得到一个相对稳定的性能。切记,在测试每个kernel的运行情况的时候,需要将GPU的频率锁在最高频,通过下面的代码就可以做到,由于我用到的A10,A10最大频率在1695 MHz

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sudo nvidia-smi --lock-gpu-clocks=1695,1695

这是通过对fp16的输入,acc_type = fp32,最终输出为fp16的batch gemm (16x4096x4096, 16x4096x4096)

通过nsight system + nvtx就可以看到每个kernel的具体实现情况:

img

添加图片注释,不超过 140 字(可选)

使用torch.bmm/torch.matmul来实现batch-gemm,其中调用的kernel名字为ampere_fp16_s1688gemm_fp16_256x64_Idg8_f2f_stages_32x1_nn,该kernel运行的时间是46.059ms

那么,当我们运行triton的时候,通过同样的方式来得到同样迭代次序的kernel,nsight分析如下

img

该kernel的名字为matmul_kernel_0d1d2d3d4d5d6d7d8d9c10d11d12c13d14d15c,运行时间为35.067ms

当然通过torch.matmul调用的cuBLAS这个算子,显然不是我们想要的那个,我们就需要去深入到cuBLAS的具体文档,翻一翻,找出其最快的API。在后面的benchmark中,我选用了cublasHgemmStridedBatched和cublasGemmStrideBatchedEx这两个API来分别实现batch GEMM。通过cublasHgemmStridedBatched启动kernel名字为ampere_h16816gemm_256x128_Idg8_stages_32x3_nn,其运行时间为30.330ms

img

通过cuBLAS的cublasGemmStridedBatchedEx API构建算子性能标准

在cuBLAS中,针对batch gemm的实现有很多种方式,我也踩了不少坑。第一次调用成了cublasHgemmStridedBatched,该kernel的性能其实是不如cublasGemmStridedBatchedEx,因为cublasGemmStridedBatchedEx给了一个cublasGemmAlgo_t algo的参数,该参数可以帮我们选择对应batch gemm的不同实现,关于algo又具有如下这么多种:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    CUBLAS_GEMM_DEFAULT,
    CUBLAS_GEMM_ALGO0,
    CUBLAS_GEMM_ALGO1,
    CUBLAS_GEMM_ALGO2,
    CUBLAS_GEMM_ALGO3,
    CUBLAS_GEMM_ALGO4,
    CUBLAS_GEMM_ALGO5,
    CUBLAS_GEMM_ALGO6,
    CUBLAS_GEMM_ALGO7,
    CUBLAS_GEMM_ALGO8,
    CUBLAS_GEMM_ALGO9,
    CUBLAS_GEMM_ALGO10,
    CUBLAS_GEMM_ALGO11,
    CUBLAS_GEMM_ALGO12,
    CUBLAS_GEMM_ALGO13,
    CUBLAS_GEMM_ALGO14,
    CUBLAS_GEMM_ALGO15,
    CUBLAS_GEMM_ALGO16,
    CUBLAS_GEMM_ALGO17,
    CUBLAS_GEMM_DFALT_TENSOR_OP,
    CUBLAS_GEMM_ALGO0_TENSOR_OP,
    CUBLAS_GEMM_ALGO1_TENSOR_OP,
    CUBLAS_GEMM_ALGO2_TENSOR_OP,
    CUBLAS_GEMM_ALGO3_TENSOR_OP,
    CUBLAS_GEMM_ALGO4_TENSOR_OP,
    CUBLAS_GEMM_ALGO18,
    CUBLAS_GEMM_ALGO19,
    CUBLAS_GEMM_ALGO20,
    CUBLAS_GEMM_ALGO21,
    CUBLAS_GEMM_ALGO22,
    CUBLAS_GEMM_ALGO23,
    CUBLAS_GEMM_ALGO5_TENSOR_OP,
    CUBLAS_GEMM_ALGO6_TENSOR_OP,
    CUBLAS_GEMM_ALGO7_TENSOR_OP,
    CUBLAS_GEMM_ALGO8_TENSOR_OP,
    CUBLAS_GEMM_ALGO9_TENSOR_OP,
    CUBLAS_GEMM_ALGO10_TENSOR_OP,
    CUBLAS_GEMM_ALGO11_TENSOR_OP,
    CUBLAS_GEMM_ALGO12_TENSOR_OP,
    CUBLAS_GEMM_ALGO13_TENSOR_OP,
    CUBLAS_GEMM_ALGO14_TENSOR_OP,
    CUBLAS_GEMM_ALGO15_TENSOR_OP,

其中,带有_TENSOR_OP后缀的则为调用tensor core来加速运算的。看到这么多种实现,不要慌,通过一个for-loop的遍历,就可以方便的找到速度最快的那一个,然后对应就可以得到TFLOPS,对应实现如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  float min_time = 0xffff;
  cublasGemmAlgo_t algo_index;
  for (const auto &algo : algoList) {
    float total_time = 0.0;
    for (int i = 0; i < iteration; i++) {

      cudaEvent_t start, end;
      cudaEventCreate(&start);
      cudaEventCreate(&end);

      cudaEventRecord(start, 0);
      cublasGemmStridedBatchedEx(
          handle, CUBLAS_OP_N, CUBLAS_OP_N, m, n, k, &alpha, d_a, CUDA_R_16F, k,
          m * k, d_b, CUDA_R_16F, n, k * n, &beta, d_c, CUDA_R_16F, n, m * n,
          batch_count, CUDA_R_16F, static_cast<cublasGemmAlgo_t>(algo));
      cudaEventRecord(end, 0);
      cudaEventSynchronize(end);
      float elapsed_time;
      cudaEventElapsedTime(&elapsed_time, start, end);
      total_time += elapsed_time;
    }
    float current_time = total_time / iteration;
    std::cout << "algo:" << algo << " " << current_time << " ms" << std::endl;
    if( current_time < min_time ) {
      min_time = current_time;
      algo_index = algo;
    }
  }
  std::cout << "best:" << algo_index << " " << min_time << " ms" << std::endl;

通过CUTLASS实现batch GEMM算子

CUTLASS这里就不花过多的篇幅进行介绍了,知乎上有很多比较详细的文章,建议做GPU性能优化的同学都能够好好研究下CUTLASS,不得不说,CUTLASS的抽象层级做的确实很好,通过暴露出对应的C++模版,就可以通过这些模版组合成很多工程开发实际中可以跑的很快的算子,而且相比于直接写CUDA嵌入PTX的汇编来说,开发的难易程度也被很大程度的降低,同时能带来和cuBLAS肩比肩的效果。在本次benchmark的构建中,我使用的是2.9.1版本的CUTLASS,在编译的时候一定要打开所有的kernel,然后通过下面的命令进行配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1. git clone https://github.com/NVIDIA/cutlass.git 
2. git checkout v2.9.1
3. export CUDACXX=/usr/local/cuda/bin/nvcc
4. mkdir build && cd build
5. cmake .. -DCUTLASS_NVCC_ARCHS=80 -DCUTLASS_LIBRARY_KERNELS=all
6. make cutlass_profiler -j16

然后我们可以通过使用cutlass_profiler来找到目前CUTLASS中针对应尺寸算子的TFLOPS最优的那个实现。这里直接使用如下代码就可以得到CUTLASS对应的实现,同时只要在对应的workload添加不同尺寸的GEMM。

Triton, CUTLASS, cuBLAS性能对比

通过上述的讲解,我们将所有的输入和计算过程与cublasGemmStridedBatchedEx中的参数对齐,输入为fp16,输出为fp16,Accumulator_type也改为fp16。在triton中需要将如下代码进行替换:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    # acc = tl.zeros((BLOCK_SIZE_M, BLOCK_SIZE_N), dtype=tl.float32)
    acc = tl.zeros((BLOCK_SIZE_M, BLOCK_SIZE_N), dtype=tl.float16)

    # acc += tl.dot(a, b)
    acc += tl.dot(a, b, out_dtype=tl.float16)

然后把他们全部画出来,纵坐标表示的TFLOPS,横坐标对应矩阵的shape,batch=16。我们可以看出来,目前我这个版本的tirton代码其实性能并不是很好,原因有很多,这个后面我给大家慢慢分析,最重要的其实就是triton.autotune中那些参数的选取和设定,以及后端的一些优化。cublasGemmStridedBatchedEx中最快的那个algo可以看出来目前基本上占据了领先位置,也就是为什么会被称为目前GPU上去做计算密集型算子优化的上届,CUTLASS在某些尺寸上的batch gemm还是表现的很优秀的,但是距离最快的cublasGemmStridedBatchedEx仍然有一些差距,不过只能说CUTLASS的优化真的牛逼,至少我知道目前国内很多HPC的组在开发对应的kernel的时候,都是选择直接魔改拼接CUTLASS的组件来加快整个开发流程。

img

总结

通过上述对batch gemm性能的分析,我们可以看出来triton距离cuBLAS的性能还有一定的距离要走,在后续的教程中,我们将结合Triton Dialect, TritonGPU Dialect, 以及Triton中autotuner作为核心组件来对Triton的所有优化过程中有一个清晰的认识。以及通过编译手段,一步一步来逼近cuBLAS的性能,甚至超越他。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-05-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GiantPandaCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
OpenAITriton MLIR 第一章 Triton DSL
上一章的反响还不错,很多人都私信催更想看Triton的具体优化有哪些,为什么它能够得到比cuBLAS更好的性能。大家不用急,这也是我为什么要写这一系列文章的初衷,来带着大家从Triton的DSL前端一步一步到最终的machine code生成有一个清晰的理解,从而为大家展示编译在高性能计算中所起到的作用。先来看看openai对Triton所打的广告:
BBuf
2023/08/25
1.2K0
OpenAITriton MLIR 第一章 Triton DSL
OpenAI/Triton MLIR 第四章: ROCm-triton配置
最近在整理python-based的benchmark代码,反过来在NV的GPU上又把Triton装了一遍,发现Triton的github repo已经给出了对应的llvm的commit id以及对应的编译细节,然后跟着走了一遍,也顺利的安装成功,只需要按照如下方式即可完成NV GPU上的安装,
BBuf
2024/02/29
1.1K0
OpenAI/Triton MLIR 第四章: ROCm-triton配置
【BBuf的CUDA笔记】十四,OpenAI Triton入门笔记三 FusedAttention
继续Triton的学习,这次来到 https://triton-lang.org/main/getting-started/tutorials/06-fused-attention.html 教程。也就是如何使用Triton来实现FlashAttention V2。对于FlashAttention和FlashAttention V2网上已经有非常多的介绍了,大家如果感兴趣的话我推荐FlashAttention V1看 《图解大模型计算加速系列:FlashAttention V1,从硬件到计算逻辑》https://zhuanlan.zhihu.com/p/669926191 这篇文章的讲解 以及 FlashAttention V2 看 《图解大模型计算加速系列:Flash Attention V2,从原理到并行计算》 https://mp.weixin.qq.com/s/5K6yNj23NmNLcAQofHcT4Q ,原理和公式推导都非常清晰,不过想一口气读完还是要花一些精力的。同时你也可以在 https://github.com/BBuf/how-to-optim-algorithm-in-cuda 找到更多相关资料(此外Meagtron-LM,DeepSpeed等训练Infra框架的迅速跟进也说明了FlashAttention这个系列工作影响之大),例如:
BBuf
2024/02/29
2.4K0
【BBuf的CUDA笔记】十四,OpenAI Triton入门笔记三 FusedAttention
【BBuf的CUDA笔记】十三,OpenAI Triton 入门笔记一
2023年很多mlsys工作都是基于Triton来完成或者提供了Triton实现版本,比如现在令人熟知的FlashAttention,大模型推理框架lightllm,diffusion第三方加速库stable-fast等灯,以及很多mlsys的paper也开始使用Triton来实现比如最近刚报道的这个新一代注意力机制Lightning Attention-2:无限序列长度、恒定算力开销、更高建模精度。当然笔者由于目前由于工作需要也需要用Triton,所以就有了这系列Triton学习笔记。本篇文章开始入门一下OpenAI的Triton,然后首先是从Triton介绍博客看起,然后对triton官方实现的vector_add和fused_softmax还有Matmul教程做一个阅读,也就是 https://triton-lang.org/main/getting-started/tutorials/ 这里的前三节,熟悉一下triton编写cuda kernel的语法。
BBuf
2024/01/23
3K0
【BBuf的CUDA笔记】十三,OpenAI Triton 入门笔记一
《PytorchConference2023 翻译系列》7-深入探索CUTLASS:如何充分利用Tensor Cores​​
嗨,我们要开始了。我叫马修·尼斯利。我是NVIDIA的深度学习compiler PM,今天我将介绍一些针对NVIDIA Tensorcores的使用方法。首先我要讲一下Cutlass。我会给你一些背景和概述,为什么你可能会使用它,一些最新和即将推出的功能,然后我会概述一下开放平台Triton。如果你刚刚参加了上一场讲座的话那你已经是懂哥了。
BBuf
2023/12/28
2.3K0
《PytorchConference2023 翻译系列》7-深入探索CUTLASS:如何充分利用Tensor Cores​​
【BBuf的CUDA笔记】十四,OpenAI Triton入门笔记二
接着【BBuf的CUDA笔记】十三,OpenAI Triton 入门笔记一 继续探索和学习OpenAI Triton。这篇文章来探索使用Triton写LayerNorm/RMSNorm kernel的细节。
BBuf
2024/02/22
1.1K0
【BBuf的CUDA笔记】十四,OpenAI Triton入门笔记二
Triton-Lang在Transformer优化加速中的实践 | 得物技术
众所周知,英伟达(Nvidia)自2006年推出CUDA以来,经过近20年的发展,尤其是经历了以卷积为代表的深度学习和近两年以Transformer为基础的LLM的推动,CUDA编程基本上成为了GPU编程的代名词。CUDA作为GPU的编程语言,不仅使用户能充分发挥Nvidia GPU的高性能的并行计算能力,也逐渐构筑了一个包括硬件、驱动、开发库和编程技巧的完备生态链,从而使CUDA成为了人工智能、高性能计算和云计算中的核心依赖。
得物技术
2025/01/14
3080
Triton-Lang在Transformer优化加速中的实践 | 得物技术
flash-linear-attention的fused_recurrent_rwkv6 Triton实现精读
继续补 在GPU上加速RWKV6模型的Linear Attention计算 没有写完的内容,对flash-linear-attention库(https://github.com/sustcsonglin/flash-linear-attention)中的fused_recurrent_rwkv6和chunk_rwkv6的前向实现进行解析,也是对Triton写cuda kernel进行继续学习。这里先解读一下fused_recurrent_rwkv6的实现,chunk_rwkv6的实现后续随缘说。
BBuf
2024/05/21
2160
flash-linear-attention的fused_recurrent_rwkv6 Triton实现精读
RT-DETR优化改进:Backbone改进 | VanillaNet一种新视觉Backbone,极简且强大!华为诺亚2023
本文独家改进: VanillaNet助力RT-DETR ,替换backbone,简到极致、浅到极致!深度为6的网络即可取得76.36%@ImageNet的精度,深度为13的VanillaNet甚至取得了83.1%的惊人性能。
AI小怪兽
2023/11/20
8180
大幅优化推理过程,字节高性能Transformer推理库获IPDPS 2023最佳论文奖
论文《ByteTransformer: A High-Performance Transformer Boosted for Variable-Length》提出了字节跳动的 GPU Transformer 推理库 ——ByteTransformer。针对自然语言处理常见的可变长输入,论文提出了一套优化算法,这些算法在保证运算正确性的前提下,成功避免了传统实现中的冗余运算,实现了端到端的推理过程的大幅优化。另外,论文中还手动调优了 Transformer 中的 multi-head attention, layer normalization, activation 等核心算子, 将 ByteTransformer 的推理性提升至业界领先水平。与 PyTorch, TensorFlow, NVIDIA FasterTransformer, Microsoft DeepSpeed-Inference 等知名的深度学习库相比,ByteTransformer 在可变长输入下最高实现 131% 的加速。论文代码已开源。
机器之心
2023/08/04
1.5K0
大幅优化推理过程,字节高性能Transformer推理库获IPDPS 2023最佳论文奖
CUDA-MODE 课程笔记 第一课: 如何在 PyTorch 中 profile CUDA kernels
一直想系统看一下某个课程系统和科学的学习下 CUDA ,感觉 CUDA-MODE 这个课程能满足我的需求。这个课程是几个 PyTorch 的 Core Dev 搞的,比较系统和专业。不过由于这个课程是 Youtube 上的英语课程,所以要学习和理解这个课程还是需要花不少时间的,我这里记录一下学习这个课程的每一课的笔记,希望可以通过这个笔记帮助对这个课程以及 CUDA 感兴趣的读者更快吸收这个课程的知识。这个课程相比于以前的纯教程更加关注的是我们可以利用 CUDA 做什么事情,而不是让读者陷入到 CUDA 专业术语的细节中,那会非常痛苦。伟大无需多言,感兴趣请阅读本文件夹下的各个课程的学习笔记。
BBuf
2024/07/02
8740
CUDA-MODE 课程笔记 第一课: 如何在 PyTorch 中 profile CUDA kernels
在GPU上加速RWKV6模型的Linear Attention计算
本文主要讲一些看到的RWKV 6模型的Linear Attention模块推理加速方法,在这篇博客中暂不涉及对kernel的深入解析。首先,flash-linear-attention(https://github.com/sustcsonglin/flash-linear-attention )这个仓库旨在对各种线性Attention架构进行工程加速,例如RetNet,GLA,Manba,RWKV6(2024年4月引入)。它使用Triton来编写代码,并针对不同的线性Transformer架构使用不同的优化方式。例如对于RWKV 6就采用在时间维度进行kernel fuse的方式来加速。其次,RWKV-CUDA是RWKV系列模型迭代中针对Linear Attention模块的改进开发的自定义高性能cuda kernel(https://github.com/BlinkDL/RWKV-CUDA)。flash-rwkv(https://github.com/BBuf/flash-rwkv)仓库在RWKV-CUDA的最优性能算子的基础上进行了封装,提供了rwkv5_cuda_linear_attention和rwkv6_cuda_linear_attention两个接口方便在HuggingFace模型实现中直接加速推理的prefill阶段速度。
BBuf
2024/05/13
4240
在GPU上加速RWKV6模型的Linear Attention计算
AMD GPU性能暴涨7倍,优化算法首次开源!高效MoE支持任意专家数量
MoE(Mixture of Experts)模型模仿了人脑的低功耗运作模式:功能被划分为多个独立的部分,在思考时通过自适应路由部分激活,从而提高计算效率。
新智元
2025/04/04
2340
AMD GPU性能暴涨7倍,优化算法首次开源!高效MoE支持任意专家数量
HugeCTR源码简单走读
这段时间除了开发算子之外,还在做一些推荐系统相关的工作,这期间主要看的是HugeCTR的代码,其性能优异,系统不复杂,代码结构较扁平,整体还是比较清晰。在这段时间看源码的过程中也算是对HugeCTR有一点了解,这篇博客主要梳理下HugeCTR代码的结构,以及他在MLPERF中做的一些优化。
BBuf
2022/05/27
1.7K0
HugeCTR源码简单走读
【AI系统】计算图的优化策略
除了前面提到的算子替换和算子前移等内容,本文内容将深入探讨计算图的优化策略,我们将细致分析图优化的其他重要内容,如改变数据节点的数据类型或存储格式来提升模型性能,以及优化数据的存储和访问方式以降低内存占用和数据访问时间。以上内容的理解和掌握,对于高效利用计算资源,提升算法性能具有至关重要的作用。
用户11307734
2024/12/06
2250
【论文解读】基于MLIR生成矩阵乘法的高性能GPU代码,性能持平cuBLAS
本文是对 https://arxiv.org/abs/2108.13191 这篇论文进行解读,学习一下如何基于MLIR编译器基础设施生成高效的GPU代码。本文的阅读的先后顺序分别为:
BBuf
2022/04/06
2.8K0
【论文解读】基于MLIR生成矩阵乘法的高性能GPU代码,性能持平cuBLAS
旷视MegEngine TensorCore 卷积算子实现原理
2020年5月Nvidia发布了新一代的GPU架构安培(Ampere)。其中和深度学习关系最密切的莫过于性能强劲的第三代的TensorCore,新一代的TensorCore支持了更为丰富的DL(Deep Learning)数据类型,包括了新的TesorFloat-32(TF32),Bfloat16(BF16)计算单元以及INT8,INT4和INT1的计算单元,这些计算单元为DL推理提供了全面的支持。
Amusi
2021/06/09
2.3K0
旷视MegEngine TensorCore 卷积算子实现原理
TORCH.FX第二篇——PTQ量化实操
本文紧接上一篇《实践torch.fx第一篇——基于Pytorch的模型优化量化神器》继续说,主要讲如何利用FX进行模型量化。
老潘
2023/10/19
2.3K0
TORCH.FX第二篇——PTQ量化实操
torch.backends.cudnn.benchmark ?!
大家在训练深度学习模型的时候,经常会使用 GPU 来加速网络的训练。但是说起 torch.backends.cudnn.benchmark 这个 GPU 相关的 flag,可能有人会感到比较陌生。在一般场景下,只要简单地在 PyTorch 程序开头将其值设置为 True,就可以大大提升卷积神经网络的运行速度。既然如此神奇,为什么 PyTorch 不将其默认设置为 True?它的适用场景是什么?为什么使用它可以提升效率?答案就在本文之中。
狼啸风云
2020/07/25
3.1K0
【BBuf的cuda学习笔记十】Megatron-LM的gradient_accumulation_fusion优化
这篇文章来解析一下Megaton-LM涉及到的一个优化gradient_accumulation_fusion。这里fusion的意思是在gemm接口中会将当前的结果累加到先前计算的梯度上,所有这些都在一个操作中完成,可以避免多次访问global memory提升算子的带宽。下面解析一下这个优化的调度逻辑和cuda实现。
BBuf
2023/08/25
2K0
【BBuf的cuda学习笔记十】Megatron-LM的gradient_accumulation_fusion优化
推荐阅读
相关推荐
OpenAITriton MLIR 第一章 Triton DSL
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档