Quanto: PyTorch 量化工具包

量化技术通过用低精度数据类型 (如 8 位整型 (int8)) 来表示深度学习模型的权重和激活,以减少传统深度学习模型使用 32 位浮点 (float32) 表示权重和激活所带来的计算和内存开销。

减少位宽意味着模型的内存占用更低,这对在消费设备上部署大语言模型至关重要。量化技术也使得我们可以针对较低位宽数据类型进行特殊的计算优化,例如 CUDA 设备有针对 int8float8 矩阵乘法的硬件优化。

市面上有许多可用于量化 PyTorch 深度学习模型的开源库,它们各有特色及局限。通常来讲,每个库都仅实现了针对特定模型或设备的特性,因而普适性不强。此外,尽管各个库的设计原理大致相同,但不幸的是,它们彼此之间却互不兼容。

因此,quanto 库应运而出,其旨在提供一个多功能的 PyTorch 量化工具包。目前 quanto 包含如下特性:

  • 在 eager 模式下可用 (适用于无法成图的模型),

  • 生成的量化模型可以运行于任何设备 (包括 CUDA 设备和 MPS 设备) 上,

  • 自动插入量化和反量化结点,

  • 自动插入量化后的 torch.nn.functional 算子,

  • 自动插入量化后的 torch.nn 模块 (具体支持列表见下文),

  • 提供无缝的模型量化工作流,支持包含静态量化、动态量化在内的多种模型量化方案,

  • 支持将量化模型序列化为 state_dict

  • 不仅支持 int8 权重,还支持 int2 以及 int4

  • 不仅支持 int8 激活,还支持 float8

最近,出现了很多仅专注于大语言模型 (LLM) 的量化算法,而 quanto 的目标为那些适用于任何模态的、易用的量化方案 (如线性量化,分组量化等) 提供简单易用的量化原语。

我们无意取代其他量化库,而是想通过新算法的实现门槛来促进创新,使得大家能够轻松地实现新模块,抑或是轻松组合现有模块来实现新算法。

毫无疑问,量化很困难。当前,如要实现模型的无缝量化,需要大家对 PyTorch 的内部结构有深入了解。但不用担心,quanto 的目标就是为你完成大部分繁重的工作,以便你可以集中精力在最重要的事情上,即: 探索低比特 AI 从而找出惠及 GPU 穷人的解决方案。

量化工作流

大家可以 pip 安装 quanto 包。

pip install quanto

quanto 没有对动态和静态量化进行明确区分。因为静态量化可以首先对模型进行动态量化,随后再将权重 冻结 为静态值的方式来完成。

典型的量化工作流包括以下步骤:

1. 量化

将标准浮点模型转换为动态量化模型。

quantize(model, weights=quanto.qint8, activations=quanto.qint8)

此时,我们会对模型的浮点权重进行动态量化以用于后续推理。

2. 校准 (如果上一步未量化激活,则可选)

quanto 支持校准模式。在校准过程中,我们会给量化模型传一些代表性样本,并在此过程中记录各算子激活的统计信息 (如取值范围)。

with calibration(momentum=0.9):
    model(samples)

上述代码会自动使能量化模块的激活量化功能。

3. 微调,即量化感知训练 (可选)

如果模型的性能下降太多,可以尝试将其微调几轮以恢复原浮点模型的性能。

model.train()
for batch_idx, (data, target) in enumerate(train_loader):
    data, target = data.to(device), target.to(device)
    optimizer.zero_grad()
    output = model(data).dequantize()
    loss = torch.nn.functional.nll_loss(output, target)
    loss.backward()
    optimizer.step()

4. 冻结整型权重

模型冻结后,其浮点权重将替换为量化后的整型权重。

freeze(model)

请参阅 该例 以深入了解量化工作流程。你还可以查看此 notebook,其提供了一个完整的用 quanto 量化 BLOOM 模型的例子。

  • 示例代码https://github.com/huggingface/quanto/tree/main/examples

  • Colab notebookhttps://colab.research.google.com/drive/1qB6yXt650WXBWqroyQIegB-yrWKkiwhl?usp=sharing

效果

下面我们列出了一些初步结果,我们还在紧锣密鼓地更新以进一步提高量化模型的准确性和速度。但从这些初步结果中,我们仍能看出 quanto 的巨大潜力。

下面两幅图评估了 mistralai/Mistral-7B-v0.1 在不同的量化参数下的准确度。注意: 每组的第一根柱子均表示非量化模型。

  • mistralai/Mistral-7B-v0.1https://huggingface.co/mistralai/Mistral-7B-v0.1

2cede0726ba69c8f441164ac838e4cfc.png  

65d0bddec62ff4b007ea33408335fe6c.png  

上述结果均未使用任何高级训后量化算法 (如 hqq 或 AWQ)。

  • hqqhttps://mobiusml.github.io/hqq_blog/

  • AWQhttps://github.com/mit-han-lab/llm-awq

下图给出了在英伟达 A100 GPU 上测到的词元延迟。

0123fb1b55519f13e12121a5c1d9ebb8.png  

这些测试结果都尚未利用任何优化的矩阵乘法算子。可以看到,量化位宽越低,开销越大。我们正在持续改进 quanto,以增加更多的优化器和优化算子,请持续关注我们的性能演进。

请参阅 quanto 基准测试 以了解在不同模型架构及配置下的详细结果。

  • quanto 基准测试https://github.com/huggingface/quanto/tree/main/bench/

集成进 transformers

我们已将 quanto 无缝集成至 Hugging Face transformers 库中。你可以通过给 from_pretrained API 传 QuantoConfig 参数来对任何模型进行量化!

  • transformershttps://github.com/huggingface/transformers

目前,你需要使用最新版本的 accelerate 以确保完全兼容。

  • acceleratehttps://github.com/huggingface/accelerate

from transformers import AutoModelForCausalLM, AutoTokenizer, QuantoConfig

model_id = "facebook/opt-125m"
tokenizer = AutoTokenizer.from_pretrained(model_id)

quantization_config = QuantoConfig(weights="int8")

quantized_model = AutoModelForCausalLM.from_pretrained(
    model_id,
    quantization_config= quantization_config
)

你只需在 QuantoConfig 中设置相应的参数即可将模型的权重/激活量化成 int8float8int4int2 ; 还可将激活量化成 int8float8 。如若设成 float8 ,你需要有一个支持 float8 精度的硬件,否则当执行 matmul (仅当量化权重时) 时,我们会默认将权重和激活都转成 torch.float32torch.float16 (具体视模型的原始精度而定) 再计算。目前 MPS 设备不支持 float8torch 会直接抛出错误。

quanto 与设备无关,这意味着无论用的是 CPU/GPU 还是 MPS (Apple 的芯片),你都可以对模型进行量化并运行它。

quanto 也可与 torch.compile 结合使用。你可以先用 quanto 量化模型,然后用 torch.compile 来编译它以加快其推理速度。如果涉及动态量化 (即使用量化感知训练或对激活进行动态量化),该功能可能无法开箱即用。因此,请确保在使用 transformers API 创建 QuantoConfig 时,设置 activations=None

quanto 可用于量化任何模态的模型!下面展示了如何使用 quantoopenai/whisper-large-v3 模型量化至 int8

from transformers import AutoModelForSpeechSeq2Seq

model_id = "openai/whisper-large-v3"
quanto_config = QuantoConfig(weights="int8")

model = AutoModelForSpeechSeq2Seq.from_pretrained(
   model_id,
   torch_dtype=torch.float16,
   device_map="cuda",
   quantization_config=quanto_config
)

你可查阅此 notebook,以详细了解如何在 transformers 中正确使用 quanto

  • notebookhttps://colab.research.google.com/drive/16CXfVmtdQvciSh9BopZUDYcmXCDpvgrT?usp=sharing#scrollTo=IHbdLXAg53JL

实现细节

量化张量

quanto 的核心是一些 Tensor 子类,其主要做下面两件事:

  • 将源张量按最优比例 投影至给定量化数据类型的取值范围内。

  • 将投影后的值映射至目标数据类型。

当目标类型是浮点型时,映射由 PyTorch 原生转换接口 (即 Tensor.to() ) 完成。而当目标类型是整型时,映射可以用一个简单的舍入操作 (即 torch.round() ) 来完成。

投影的目标是提高数据类型转换的精确度,具体可以通过最小化以下两个值来达成:

  • 饱和值的个数 (即有多少个数最终映射为目标数据类型的最小值/最大值),

  • 归零值的个数 (即有多少个数因为小于目标数据类型可以表示的最小数字,所以被映射成了 0)。

为了提高效率起见, 8 比特 量化时,我们使用对称投影,即以零点为中心进行投影。一般而言,对称量化张量与许多标准算子兼容。

在使用较低位宽的量化 (如 int2int4 ) 时,一般使用的是仿射投影。此时,会多一个 zeropoint 参数以对齐投影值和原值的零点。这种方法对量化范围的覆盖度会好些。仿射量化张量通常更难与标准算子兼容,因此一般需要自定义很多算子。

量化 torch.nn 模块

quanto 实现了一种通用机制,以用能够处理 quanto 张量的 quanto 模块替换相应的 torch 模块 ( torch.nn.Module )。

quanto 模块会动态对 weights 进行数据类型转换,直至模型被冻结,这在一定程度上会减慢推理速度,但如果需要微调模型 (即量化感知训练),则这么做是需要的。

此外,我们并未量化 bias 参数,因为它们比 weights 小得多,并且对加法进行量化很难获得太多加速。

我们动态地将激活量化至固定取值范围 (默认范围为 [-1, 1] ),并通过校准过程决定最佳的比例 (使用二阶动量更新法)。

我们支持以下模块的量化版:

  • Linear (QLinear)。仅量化权重,不量化偏置。输入和输出可量化。

  • Conv2d (QConv2D)。仅量化权重,不量化偏置。输入和输出可量化。

  • LayerNorm。权重和偏至均 量化。输出可量化。

  • Linearhttps://pytorch.org/docs/stable/generated/torch.nn.Linear.html

  • Conv2dhttps://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html

  • LayerNormhttps://pytorch.org/docs/stable/generated/torch.nn.LayerNorm.html

定制算子

得益于 PyTorch 出色的调度机制,quanto 支持在 transformers 或 diffusers 的模型中最常用的函数,无需过多修改模型代码即可启用量化张量。

  • diffusershttps://github.com/huggingface/diffusers

大多数“调度”功能可通过标准的 PyTorch API 的组合来完成。但一些复杂的函数仍需要使用 torch.ops.quanto 命名空间下的自定义操作。其中一个例子是低位宽的融合矩阵乘法。

训后量化优化

quanto 中尚未支持高级的训后量化算法,但该库足够通用,因此与大多数 PTQ 优化算法兼容,如 hqq、[AWQ](https:/

展望未来,我们计划无缝集成这些最流行的算法。

为 Quanto 作出贡献

我们非常欢迎大家对 quanto 作出贡献,尤其欢迎以下几类贡献:

  • 实现更多针对特定设备的 quanto 优化算子,

  • 支持更多的 PTQ 优化算法,

  • 扩大量化张量可调度操作的覆盖面。

  • quantohttps://github.com/huggingface/quanto


英文原文: https://hf.co/blog/quanto-introduction
原文作者: David Corvoysier,Younes Belkada,Marc Sun
译者: Matrix Yao (姚伟峰),英特尔深度学习工程师,工作方向为 transformer-family 模型在各模态数据上的应用及大规模模型的训练推理。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于JAVA的校园失物招领平台

采用技术 基于JAVA的校园失物招领平台的设计与实现~ 开发语言:Java 数据库:MySQL 技术:SpringMVCMyBatis 工具:IDEA/Ecilpse、Navicat、Maven 页面展示效果 管理员功能 论坛管理 失物认领管理 寻物启事管理 用户管理 失物…

如何查询运行的服务器的整机功耗?

要在Linux服务器上安装Powerstat,您可以根据所使用的Linux发行版选择适当的命令。 对于Ubuntu/Debian系统,您可以使用以下命令安装Powerstat: sudo apt-get install powerstat 对于Redhat/CentOS系统,您应该使用以下命令&#x…

ReLU Strikes Back: Exploiting Activation Sparsity in Large Language Models

iclr 2024 oral reviewer 评分 688 1 intro 目前LLM社区中通常使用GELU和SiLU来作为替代激活函数,它们在某些情况下可以提高LLM的预测准确率 但从节省模型计算量的角度考虑,论文认为经典的ReLU函数对模型收敛和性能的影响可以忽略不计,同时…

专为苹果系统设计的精美可视化图表 | 开源日报 No.219

danielgindi/Charts Stars: 27.3k License: Apache-2.0 Charts 是为 iOS/tvOS/OSX 提供美观图表的开源项目,是跨平台 MPAndroidChart 在苹果设备上的实现。该项目提供了以下主要功能和优势: 支持 iOS、tvOS 和 macOS 平台使用 Swift 编写,可…

FFmpeg: 简易ijkplayer播放器实现--01项目简介

文章目录 项目介绍流程图播放器实现过程界面展示 项目介绍 此项目基于FFmeg中 ffplay.c进行二次开发,实现基本的功能,开发软件为Qt 项目优势: 参考ijkplayer播放器,实现UI界面和播放器核心进行解耦,容易添加其他功能…

互联网轻量级框架整合之MyBatis核心组件

在看本篇内容之前,最好先理解一下Hibernate和MyBatis的本质区别,这篇Hibernate和MyBatis使用对比实例做了实际的代码级对比,而MyBatis作为更适合互联网产品的持久层首选必定有必然的原因 MyBatis核心组件 MyBatis能够成为数据持久层首选框&a…

利用图和侧信息的核概率矩阵

文章信息 本周阅读的论文是一篇2012年发表在《Proceedings of the 2012 SIAM International Conference on Data Mining》上关于概率矩阵分解的文章,题目为《Kernelized Probabilistic Matrix Factorization Exploiting Graphs and Side Information》。 摘要 我们提…

【STM32篇】DRV8425驱动步进电机

【STM32篇】4988驱动步进电机_hr4988-CSDN博客 在上篇文章中使用了HR4988实现了步进电机的驱动,在实际运用过程,HR4988或者A4988驱动步进电机会存在电机噪音太大的现象。本次将向各位友友介绍一个驱动简单且非常静音的一款步进电机驱动IC。 1.DRV8425简介…

头歌-机器学习实验 第8次实验 决策树

第1关:什么是决策树 任务描述 本关任务:根据本节课所学知识完成本关所设置的选择题。 相关知识 为了完成本关任务,你需要掌握决策树的相关基础知识。 引例 在炎热的夏天,没有什么比冰镇后的西瓜更能令人感到心旷神怡的了。现…

Fast-Planner(五)详解TopologyPRM

本文上接Fast-Planner第一篇文章的内容,本文主要详解这一系列的第二篇Robust Real-time UAV Replanning Using Guided Gradient-based Optimization and Topological Paths中的TopologyPRM即其代码。如有问题,欢迎各位大佬评论指出,带着我一起…

C语言面试题之返回倒数第 k 个节点

返回倒数第 k 个节点 实例要求 1、实现一种算法,找出单向链表中倒数第 k 个节点;2、返回该节点的值; 示例:输入: 1->2->3->4->5 和 k 2 输出: 4 说明:给定的 k 保证是有效的。实…

Unity 获取RenderTexture像素颜色值

拿来吧你~ 🦪功能介绍🌭Demo 🦪功能介绍 💡不通过Texture2D 而是通过ComputerShader 提取到RenderTexture的像素值,效率有提升哦! 💡通过扩展方法调用,方便快捷:xxxRT.G…

无人机低空数字摄影测量系统

一、 系统概述 系统完全基于IDL设计实现,包括界面布局到人机交互再到底层核心函数功能。整体设计框架基于数字摄影测量的专业处理流程,实现了数据输入、数据预处理、影像信息检测、空间定向、地形三维建模、专题信息提取、成果输出与更新等功能。同时为…

【linux】yum 和 vim

yum 和 vim 1. Linux 软件包管理器 yum1.1 什么是软件包1.2 查看软件包1.3 如何安装软件1.4 如何卸载软件1.5 关于 rzsz 2. Linux编辑器-vim使用2.1 vim的基本概念2.2 vim的基本操作2.3 vim命令模式命令集2.4 vim底行模式命令集2.5 vim操作总结补充:vim下批量化注释…

Spring AI 应用 - 智能记者

参考实现: https://github.com/mshumer/ai-journalist 上面是通过 Claude 配合 SERP 搜索 API,使用 Python 语言实现的,本文通过 GitHub Copilot 辅助改为了基于 Spring AI 的 Java 版本,本文使用的 OpenAI。 AIJournalist 实现…

绝地求生:经典杜卡迪与传奇杜卡迪的区别以及亮点

大家好,这里是闲游盒. 杜卡迪联名已正式加入PUBG,本次联名分为两个版本分别为:经典杜卡迪以及传奇杜卡迪 那接下来,就给大家展示一下经典杜卡迪(红)以及传奇版本杜卡迪(暮光粉)的区…

Acwing.4009 收集卡牌(期望dp)

题目 小林在玩一个抽卡游戏,其中有 n种不同的卡牌,编号为 1到 n。 每一次抽卡,她获得第 i种卡牌的概率为 pi。 如果这张卡牌之前已经获得过了,就会转化为一枚硬币。 可以用 k枚硬币交换一张没有获得过的卡。 小林会一直抽卡&…

2024大模型落地应用案例集(免费下载)

【1】扫码关注本公众号 【2】私信发送 2024大模型落地应用案例集 【3】获取本方案PDF下载链接,直接下载即可。

初识C++之内联函数 auto关键字

初识C之内联函数 auto关键字 文章目录 初识C之内联函数 auto关键字一、 内联函数1.1 定义1.2 应用1.3 特性 二、auto关键字2.1 简介2.2 auto的详细使用2.3 范围for(C)2.4 注意事项 一、 内联函数 1.1 定义 以inline修饰的函数叫做内联函数,…

UDP实现Mini版在线聊天室

实现原理 只有当客户端先对服务器发送online消息的时候,服务器才会把客户端加入到在线列表。当在线列表的用户发消息的时候,服务器会把消息广播给在线列表中的所有用户。而当用户输入offline时,表明自己要下线了,此时服务器把该用…