CUDA-MODE课程笔记 第7课: Quantization Cuda vs Triton

我的课程笔记,欢迎关注:https://github.com/BBuf/how-to-optim-algorithm-in-cuda/tree/master/cuda-mode

CUDA-MODE课程笔记 第7课: Quantization Cuda vs Triton

适配课件详细解读

作者课件可以在这里找到:https://github.com/cuda-mode/lectures 。我也下载里一份放在 https://github.com/BBuf/how-to-optim-algorithm-in-cuda/tree/master/cuda-mode/ppt 这里。

PyTorch最近一年发布了一些生成式AI模型的案例研究,这些模型运行速度极快,且代码及其精简。这些模型比如GPT-FAST,SAM-FAST都应用了量化技术,Charles很大程度上是这些量化Kernel的主要开发者。因此,这节课由Charles来分享量化技术。

这张Slides介绍了演讲者的背景和最近的研究重点,内容如下:

  • Pytorch Core
    • AO (Architecture Optimization) 团队
      • 量化 (Quantization)
      • 剪枝 (Pruning)
  • 最近的研究重点
    • GPU 量化
      • Segment-anything-fast, gpt-fast, sdxl-fast 等项目
      • TorchAO - 提供了一个 GitHub 链接 (https://github.com/pytorch-labs/ao)
      • Int8 动态量化
        • i8i8->i32 vs i8i8bf16->bf16
      • Int8 仅权重量化
        • bf16i8->bf16
      • Int4 仅权重量化
        • bf16i4->bf16

这张Slides介绍了三种不同的量化技术:

  • 动态量化流程 (Dynamic Quantization Flow):
    • 权重和激活都从浮点开始
    • 权重在预处理阶段量化
    • 激活在运行时量化
    • 使用Int8进行乘法运算
    • 使用Int32进行累加
    • 最后rescale回浮点数
  • 未量化 (Not Quantized):
    • 权重和激活都保持浮点格式
    • 所有运算(乘法和累加)都使用浮点数进行
  • 仅权重量化 (Weight Only Quantization):
    • 权重在预处理阶段量化
    • 随后立即反量化回浮点数
    • 激活保持浮点格式
    • 乘法和累加都使用浮点数进行
    • 最后有一个rescale步骤

总的来说,这张Slides展示了这三种技术在处理神经网络计算时的不同流程。动态量化通过在计算过程中使用整数运算来提高效率,而仅权重量化则只对权重进行压缩,在实际计算时仍使用浮点数。未量化的方法则完全使用浮点数,可能提供最高的精度但计算效率较低。

这张Slides进一步说明了动态量化(Dynamic Quantization)的概念和流程:

  • 数学表达:
    • 原始公式:Y = X.W
    • 量化后的公式:Y = (Sx*Xint).(Wint * Sw)
    • 重排后的公式:Y = Sx * (Xint.Wint) * Sw
      这里,Sx 和 Sw 是缩放因子,Xint 和 Wint 是量化后的整数值。
  • 动态量化流程图:
    • 开始于浮点权重(Float Weight)和浮点激活值(Float Activation)
    • 权重在预处理阶段进行量化(Quantize (preprocess))
    • 激活值在运行时进行量化(Quantize)
    • 使用 Int8 进行乘法运算(Multiplication (Int8))
    • 使用 Int32 进行累加运算(Accumulation (Int32))
    • 最后将结果重新缩放(Rescale (Float))回浮点数
    • 输出浮点激活值(Float Activation)

这张Slides展示了逐张量量化(per-tensor quantization)和逐token量化 + 逐通道量化(per-token + per-channel quantization)两种动态量化方式。
性能比较(以SAM模型为例,vit_h, bsz=16):

  • 无量化:运行时间 785.313 ms,峰值内存 15.279(单位未指明,可能是GB)
  • 动态量化:运行时间 731.649 ms,峰值内存 18.631
    另外,这里的链接是Triton的矩阵乘法教程。

结论:动态量化可以提高计算效率,在这个例子中,运行时间减少了约7%。不同的量化策略(逐张量、逐token、逐通道)可以应用于不同的张量,以优化性能和精度。虽然动态量化提高了计算速度,但它的显存占用却更多了大概是15%-20%。

这张Slides指出,显存增加的原因是要把int8的结果累加到int32类型中,因此相比于BFloat1增加了额外的显存。

这张Slides进一步详细介绍了动态量化(Dynamic Quantization)的概念、方法和性能比较:

  • 动态量化的数学表达:
    • 原始公式:Y = X.W
    • 量化公式:Y = (Sx*Xint).(Wint * Sw)
    • 重排公式:Y = Sx * (Xint.Wint) * Sw
    • 进一步优化:Sx * (XWrescaled)

其中使用了不同的数据类型:
- int8:用于Xint和Wint
- bf16:用于Sx和Sw
- int32:用于中间计算结果XWint

  • 性能比较(以SAM模型为例,vit_h, bsz=16):
    • 无量化:运行时间 785.313 ms,峰值内存 15.279 GB
    • 动态量化:运行时间 731.649 ms,峰值内存 18.631 GB
    • 动态量化with fusion:运行时间 695.115 ms,峰值内存 14.941 GB
      结论:动态量化可以显著提高计算效率,运行时间减少约7%。动态量化with fusion进一步优化了性能,运行时间比无量化减少约11.5%,同时还略微降低了内存使用。

这里展示的是要在Torch Compile中实现动态量化with fusion需要做出的努力,因为Torch Compile并不愿意融合乘法操作,所以作者不得不在Torch Compile的矩阵乘法kernel后强制添加一个乘法的epilogue(实际上这是一个编译器的PASS,需要匹配到矩阵乘法+乘法才能生效)。图片比较难看代码,这里贴一下:

# This op is a special case of the int_mm op which we use based on the pattern
# _int_mm -> mul (defined in ../fx_passes/post_grad.py) in order to prevent
# realization of the int32 _int_mm output by forcing fusion with the mul op.
# This is only used when config.force_fuse_int_mm_with_mul = True
def tuned_fused_int_mm_mul(mat1, mat2, mat3, out_dtype, *, layout=None):
    out_dtype = (
        torch.promote_types(mat3.get_dtype(), torch.int32)
        if out_dtype is None
        else out_dtype
    )
    m, n, k, layout, mat1, mat2, mat3 = mm_args(
        mat1, mat2, mat3, layout=layout, out_dtype=out_dtype
    )
    choices: List[Dict[Any, Any]] = [
### PyTorch Quantization CUDA 扩展模块加载时出现未定义符号错误解决方案 当遇到 `pytorch_quantization/cuda_ext.cpython-310-x86_64-linux-gnu.so: undefined symbol` 错误时,通常是因为库文件中的某些符号未能正确解析。这类问题可能由多种因素引起,包括但不限于编译环境差异、依赖项版本不兼容以及CUDA工具链配置不当。 #### 1. 版本一致性检查 确保使用的PyTorch版本与CUDA版本相匹配非常重要。不同版本之间可能存在API变化或内部实现细节的不同,这可能导致链接阶段出现问题[^4]。建议确认当前环境中安装的PyTorchCUDA版本,并查阅官方文档获取支持的具体组合列表。 #### 2. 清理并重新构建项目 有时残留的目标文件可能会干扰新版本的正常工作。尝试清理所有已有的build目录及相关缓存后再执行一次完整的构建过程: ```bash rm -rf build dist *.egg-info pip uninstall nvidia-pytorch-quantization pip install --no-cache-dir . ``` #### 3. 更新C++标准库 部分情况下,旧版的标准模板库(STL)也可能引发此类问题。更新至最新稳定版本可以有效减少因STL引起的冲突风险。对于基于Ubuntu系统的用户来说,可以通过如下命令来完成升级操作: ```bash sudo apt-get update && sudo apt-get upgrade libstdc++ ``` #### 4. 安装缺失依赖包 如果上述措施仍无法解决问题,则可能是由于缺少必要的运行时依赖造成的。特别是像`libomp-dev`这样的OpenMP开发库,在多线程计算场景下不可或缺。可通过以下方式安装该组件及其他潜在必需品: ```bash sudo apt-get install libomp-dev cmake python3-dev ``` #### 5. 修改CMakeLists.txt 文件设置 针对特定平台优化过的第三方插件,其默认编译选项未必适用于所有情况。适当调整CMakeLists.txt内的参数有助于改善跨平台移植性和稳定性。例如增加显式的RTTI(Run-Time Type Information)开关: ```cmake set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti") ``` 通过以上几个方面的排查与修正,应该能够较好地处理大多数类似的未定义符号异常状况。当然,具体实施过程中还需结合实际情况灵活应对。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值