使用PyTorch在AMD GPU上进行INT8量化实现精简化的LLM推理

ops/2024/11/30 7:26:04/

Leaner LLM Inference with INT8 Quantization on AMD GPUs using PyTorch — ROCm Blogs

随着大型语言模型(LLMs)规模达到数千亿参数,我们在这些庞大模型中表示数据的方式极大地影响了训练所需的资源(例如,用于推理的GPU数量)。在我们之前的博客(JAX混合精度训练;PyTorch AMP)中,我们已经展示了混合精度训练如何加速LLMs的训练过程。在这篇博客文章中,我们将进一步推进,向您展示如何通过量化到更低精度的数据格式来加速推理,节省时间和内存,而不会牺牲模型的整体性能。量化是一种技术,通过将模型参数的精度从32位浮点(FP32)或16位浮点(FP16)减少到8位整数(INT8)。标准模型通常使用32位浮点(FP32)精度。然而,对于推理任务来说,这种高精度并不是总是必要的。通过将模型权重和激活转换为较低精度格式如INT8(8位整数),我们可以实现更快的计算和更低的内存使用,有效地将模型大小减少到原来的四分之三(从32位)或一半(从16位),仅有轻微的准确性下降,这常常被速度提升所弥补。

在这篇博客文章中,我们将逐步向您展示如何使用ROCm、PyTorch和gpt-fast repository在AMD GPU上实现INT8量化,以及如何评估由此产生的推理性能。具体来说,我们将演示INT8量化如何显著提升Llama系列和Mistral LLM模型的推理速度。

如何进行量化

大多数模型量化技术可以分为以下两类:

  • 训练后量化(PTQ):在模型完全训练后应用。这种方法更简单,但可能会导致一定的性能损失。

  • 量化感知训练(QAT):在训练过程中引入量化,使量化后的权重能够更好地捕捉数据的信息。它通常能带来更好的结果,但需要更多的计算资源。

关于这两种策略的更多信息,请参见LLM 系列 - 量化概述。

对于我们下面的代码示例,我们将使用 PTQ。以下是 PTQ 的一般步骤,尽管实际步骤在不同应用中可能会有很大差异。

1. 模型准备

  • *加载预训练模型*:从一个预训练模型开始,通常是 FP32、FP16 或 BF16 格式。

  • *定义量化配置*:指定量化方案和配置,例如对称量化或非对称量化,以及按通道或按张量量化。

2. 校准

  • *收集校准数据*:收集一个代表性的数据集,以捕捉模型在推理期间遇到的输入分布。

  • *运行校准*:使用校准数据运行模型并收集统计数据,例如每层激活的最小值和最大值。此步骤确定权重和激活的量化参数(比例和零点)的值。这些比例和零点参数类似于标准化中的标准差和均值。

3. 量化和模型转换

  • *量化权重和激活*:使用校准步骤中确定的量化参数值,将较高精度的权重和激活量化为 INT8。

  • *转换模型格式*:使用像 PyTorch 这样的框架将模型转换为量化格式。

在我们的演示中,我们将只对权重进行量化,并跳过校准过程。权重的分布是已知且固定的,可以直接从权重值本身计算出量化比例和零点参数。

实现

在官方的 gpt-fast repository 中,作者测量了 meta-llama/Llama-2-7b-chat-hf 模型在 MI-250x GPU 上的推理速度,重点关注模型处理数据的速度。然而,在实际环境中评估推理效率时,还需要考虑吞吐量,它是衡量在给定时间内能处理多少数据(在这种情况下是 tokens)。吞吐量通常以 Tokens/Second 表示,提供了模型在实际应用中性能的更全面理解。

在我们的实现中,我们将使用与 MI-250x GPU 的一个 GCD(图形计算芯片)等效的 MI210 GPU(一个 MI-250x GPU 可以看作两个 MI210 GPU)。我们将测量 Llama-2-7B 推理吞吐量作为基准,然后将测试扩展到另外三个流行的模型:`meta-llama/Meta-Llama-3-8B`(Llama 家族模型的较新版本)、`mistralai/Mistral-7B-v0.1` 和 meta-llama/Llama-2-13b-chat-hf。对于每个模型,我们将测试三种不同优化水平的模式以确定其性能:

  1. Eager 模式(无优化)

  2. Torch.compile

  3. Torch.compile + INT8 量化

torch.compile 是 PyTorch 的一个功能,通过将模型执行转换为更高效的编译形式来优化模型执行,从而提高运行时性能。

我们将使用带有每晚构建 PyTorch 的 ROCm Docker 容器进行演示。PyTorch 持续改进,每晚版本通常包含最新的优化。Docker 容器将在运行 Ubuntu 的 AMD GPUs 服务器上运行。

请参阅 System requirements (Linux) 了解 AMD 支持的硬件和操作系统的完整列表。

  • 使用以下命令在 Linux 终端中拉取和运行 Docker 容器:

    docker run -it --ipc=host --network=host --device=/dev/kfd --device=/dev/dri \--group-add video --cap-add=SYS_PTRACE --security-opt seccomp=unconfined \--name=pt_nightly rocm/pytorch-nightly:latest /bin/bash
    

    您可以通过在 Python 控制台中运行以下代码来查看 PyTorch 检测到的 GPUs 数量。PyTorch 至少需要检测到一块 GPU。

    import torch
    torch.cuda.device_count()
    
  • 安装所需的 Python 包:

    python3 -m pip install --upgrade pip
    pip install sentencepiece huggingface_hub tiktoken blobfile
    
  • 使用以下命令下载 gpt-fast 仓库:

    git clone https://github.com/pytorch-labs/gpt-fast.git
    
  • 下载 generate.py 和 run_commands.sh 文件,获取地址为 此博客srcGitHub 文件夹。将 generate.py 和 run_commands.sh 放在下载的 gpt-fast 文件夹中,替换原始的 generate.py 文件。`gpt-fast` 仓库中的原始 generate.py 文件仅仅在基准模型上计算每秒处理的平均 tokens 数,而不排除前几轮的热身,这可能导致结果偏差。我们修改并增强了 generate.py 文件:

    • 运行总共 30 次迭代,前 20 次迭代作为热身,并计算最后 10 轮的平均值和标准差。

    • 计算内存带宽的平均值和标准差。

运行基准模型并收集指标

下面是一个名为`run_commands.sh`的文件,它包含了下载、量化和运行基准模型以收集推理指标 Tokens/Second 和 Memory Bandwidth (GB/s) 的命令。

您需要提供您的 Hugging Face 凭据才能运行 run_commands.sh。通过运行 huggingface-cli login 并按照提示操作来提供您的凭据。有关如何获得 Hugging Face 访问令牌的信息,请参阅 Hugging Face 用户文档中的 用户访问令牌 。

#!/bin/bash# 日志文件
LOGFILE="output_4_models.log"# 如果日志文件存在则清除
> $LOGFILE# 模型仓库数组
MODEL_REPOS=("meta-llama/Llama-2-7b-chat-hf" "meta-llama/Meta-Llama-3-8B" "mistralai/Mistral-7B-v0.1" "meta-llama/Llama-2-13b-chat-hf")# 运行命令并记录输出
{echo "Processing models"# 循环遍历模型仓库for MODEL_REPO in "${MODEL_REPOS[@]}"; do# 准备/下载模型./scripts/prepare.sh $MODEL_REPOecho -e "\n**************正在运行基线模型 $MODEL_REPO..."python generate.py --checkpoint_path checkpoints/$MODEL_REPO/model.pth --prompt "Hello, my name is"echo -e "\n**************正在运行 torch.compile 模型 $MODEL_REPO..."python generate.py --compile --checkpoint_path checkpoints/$MODEL_REPO/model.pth --prompt "Hello, my name is"echo "Setting DEVICE to cuda..."export DEVICE=cudaecho -e "\n**************正在量化并运行命令  $MODEL_REPO..."python quantize.py --checkpoint_path checkpoints/$MODEL_REPO/model.pth --mode int8echo -e "\n**************运行 int8 模型 $MODEL_REPO..."python generate.py --compile --checkpoint_path checkpoints/$MODEL_REPO/model_int8.pth --device $DEVICEdone
} &> $LOGFILE

在 gpt-fast 文件夹中运行 ./run_commands.sh 来收集指标。

基准测试结果

在下表中,我们展示了每种推理模式下各个模型的指标。在最后一列中可以看到,与torch compile模式相比,INT8量化通过量提高了大约25-45%,与eager模式相比甚至更多。这证实了模型量化可以用来提升大规模语言模型(LLMs)的推理性能。

模型(模式)每秒Token数内存带宽(GB/s)

T/S Ratio to Eager相对于Eager模式的T/S比率

相对于Compile模式的T/S比率

Llama-2-7B (eager)

33.29

439.97

1

-

Llama-2-7B (compile)

88.54

1170.01

2.66

1

Llama-2-7B (compile + INT8)

112.45

743.31

3.38

1.27

Llama-3-8B (eager)

32.52

488.06

1

-

Llama-3-8B (compile)

76.88

1154.01

2.36

1

Llama-3-8B (compile + INT8)

110.35

828.50

3.39

1.44

Mistral-7B (eager)

32.68

464.77

1

-

Mistral-7B (compile)

81.44

1158.20

2.49

1

Mistral-7B (compile + INT8)

117.05

832.67

3.58

1.44

Llama-2-13B (eager)

21.36

549.01

1

-

Llama-2-13B (compile)

44.79

1151.30

2.10

1

Llama-2-13B (compile + INT8)

59.62

766.58

2.79

1.33

总结

在这篇博客文章中,我们逐步向您展示了如何使用AMD GPU实现INT8量化,并如何基准测试结果推理。我们展示了INT8量化对Llama系列和Mistral大型语言模型训练的加速效果。

致谢

我们要感谢PyTorch Labs开发的 gpt-fast 仓库,它为我们的工作提供了指南。 


http://www.ppmy.cn/ops/137864.html

相关文章

二阶信息在机器学习中的优化;GPTQ算法利用近似二阶信息;为什么要求近似二阶(运算量大,ReLu0点不可微)

目录 二阶信息在机器学习中的优化 GPTQ算法利用近似二阶信息来找到合适的量化权重 详细解释 举例说明 近似二阶信息 定义与解释 举例说明 总结 为什么要求近似二阶(运算量大,ReLu0点不可微) 计算复杂性 精度需求 实际应用场景中的权衡 二阶信息在机器学习中的优…

利用爬虫爬取网页小说

需求分析 安装requests包 pip install requests目录采集地址: h t t p s : / / w w w . 3 b q g . c c / b o o k / 60417 / https://www.3bqg.cc/book/60417/ https://www.3bqg.cc/book/60417/ 章节采集地址: h t t p s : / / w w w . 3 b q g . c …

【代码随想录day44】【C++复健】1143.最长公共子序列;1035.不相交的线;53. 最大子序和;392. 判断子序列

1143.最长公共子序列 本题一开始以为是和前面那个一维递增子序列一样,dp数组的[i][j]表示的是以i,j为结尾的最长公共子序列,然后用两个for循环去前面找前缀对应的最大值,这样写出来的代码算上遍历总共要4次for循环,结…

【NLP】第三章:长短期记忆网络LSTM

三、长短期记忆网络LSTM 循环神经网络的特点就是拥有"记忆",就是考虑历史信息,从历史信息中获取辅助当前的决策。 按记忆能力分:simple rnn(就是前面讲的简单rnn结构)、长短期记忆网络(LSTM)、门控循环单元(GRU)、以及双向RNN(Bi-…

shell脚本基础学习_总结篇(完结)

细致观看可以,访问shell脚本学习专栏,对应章节会有配图https://blog.csdn.net/2201_75446043/category_12833287.html?spm1001.2014.3001.5482 导语 一、shell脚本简介 1. 定义: 2. 主要特点: 3. shell脚本的基本结构 4. S…

快速搭建一个博客!!!“Halo框架深度优化:搭建你的个性化博客或网站”

目录 引言: 一. 首先服务器上去下载一个docker 1.可以参考官方地址: 2. 通过宝塔来一键安装!!! 3.也可以自己下载!!! 1.卸载旧版 2.配置Docker的yum库 3.安装Docker 4.启动和…

TypeScript 命名空间与模块

在 TypeScript 中,命名空间和模块是两种不同的代码组织方式,它们都旨在帮助你管理和维护大型代码库。命名空间提供了一种将相关功能组织在一起的方式,而模块则允许你将代码分解成可重用的单元。在本文中,我们将探讨命名空间和模块…

探索文件系统,Python os库是你的瑞士军刀

文章目录 探索文件系统,Python os库是你的瑞士军刀第一部分:背景介绍第二部分:os库是什么?第三部分:如何安装os库?第四部分:简单库函数使用方法1. 获取当前工作目录2. 改变当前工作目录3. 列出目…