Quanto: PyTorch 量化工具包

news2025/6/22 16:46:09

量化技术通过用低精度数据类型 (如 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 模型在各模态数据上的应用及大规模模型的训练推理。

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

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

相关文章

Python学习从0开始——项目一day01爬虫

Python学习从0开始——项目一day01爬虫 一、导入代码二、使用的核心库三、功能测试3.1初始代码3.2新建文件3.3代码调试 四、页面元素解析4.1网页4.2修改代码4.3子页面4.4修改代码 一、导入代码 在Inscode新建一个python类型的项目,然后打开终端,粘贴以下…

高中数学:三角函数-基础知识

一、任意角 顺时针旋转是负值角 逆时针旋转式正值角 一个角对应一个终边 一个终边对应无数个角 xk*360 例题 二、弧度制 弧长与半径的比值,就是角度 常见角度与弧度的对应关系 例题 三、弧长与扇形面积公式 注意:弧度制下的扇形面积公式&#x…

SpringBoot --pagehelper分页

目录 1.建立数据库 2.页面显示 3.基本逻辑 4.配置依赖 5.使用pagehelper 6.页面列表 页面 效果 1.建立数据库 create database if not exists my_book; use my_book; create table if not exists myBook (id int primary key auto_increment,name varchar(50) not …

Python(4):函数(命名+参数+内置函数+匿名函数)

文章目录 一、关于*的一些打散功能二、函数的特点和命名规范三、函数的返回值return四、函数的参数1.无参数的函数2.有参数的函数 五、函数的命名空间六、全局变量和局部变量七、函数的作用域以及执行顺序(LEGB)八、递归函数九、常见内置函数十、匿名函数-lambda 一、关于*的一…

c++的学习之路:11、string(3)

昨天写string的时候没有说全,这里就开始接着讲。 目录 一、resize 二、insert 三、erase 一、resize 昨天说这个的时候没有考虑到缩小范围时咋处理,然后发现报错了,接着我调试发现缩小就不能正常执行了,因为用的是strcap所以…

芯片设计围炉札记

文章目录 语言Verilog 和 VHDL 区别 芯片验证 语言 System Verilog的概念以及与verilog的对比 IC 设计软件分析 Verilog 和 VHDL 区别 Verilog HDL 和 VHDL 的区别如下: 语法结构:Verilog的语法结构类似于C语言,而VHDL的语法结构则更接近…

流程图步骤条

1.结构 <ul class"stepUl"> <li class"stepLi" v-for"(item, index) in stepList" :key"index"> <div class"top"> <p :class"{active: currentState > item.key}">{{ item.value }}…

没有公网IP怎么办?

在网络通信中&#xff0c;公网IP是指可以直接访问互联网的IP地址。由于各种原因&#xff0c;有一些用户可能没有自己的公网IP地址。那么没有公网IP的情况下&#xff0c;我们应该怎么办呢&#xff1f; 局域网的限制 我们需要了解局域网的概念。局域网是指在一个相对较小的范围内…

R语言记录过程

如何使用这个函数as.peakData 函数构造过程 出现问题是缺少函数的问题 up不告诉我&#xff0c;这里是代表c,h,o的值&#xff0c;你从里面获取把值&#xff0c;设置成c,h,o就可以了 现在开始测试参数 第一次 startRow : 开始查找数据的第一行。不管startRow的值是多少&#xff…

3D Matching:实现halcon中的find_surface_model

halcon中的三维匹配大致分为两类&#xff0c;一类是基于形状的(Shape-Based)&#xff0c;一类是基于表面的(Surface-Based)。基于形状的匹配可用于单个2D图像中定位复杂的3D物体&#xff0c;3D物体模型必须是CAD模型&#xff0c;且几何边缘清晰可见&#xff0c;使用的相机也要预…

2024年能源环境、材料科学与人工智能国际会议(ICEEMSAI2024)

2024年能源环境、材料科学与人工智能国际会议(ICEEMSAI2024) 会议简介 2024国际能源环境、材料科学和人工智能大会&#xff08;ICEEMSAI 2024&#xff09;主要围绕能源环境、物质科学和人工智慧等研究领域&#xff0c;旨在吸引能源环境、先进材料和人工智能专家学者、科技人员…

虹科Pico汽车示波器 | 免拆诊断案例 | 2011款东风悦达起亚K5车发动机偶尔起动困难

一、故障现象 一辆2011款东风悦达起亚K5车&#xff0c;搭载G4KD发动机&#xff0c;累计行驶里程约为24.5万km。车主反映&#xff0c;第1次起动发动机时偶尔无法起动着机&#xff0c;第2次能够正常起动着机&#xff0c;但发动机故障灯异常点亮。为此在其他维修厂维修过&#xf…

【今日刷题】LeetCode 199.二叉树的右视图(中等)

今日刷题&#xff1a;LeetCode 199.二叉树的右视图&#xff08;中等&#xff09; 题目描述&#xff1a; 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,…

取证——流量分析2

计算流量包文件的SHA256值是&#xff1f;[答案&#xff1a;字母小写][★☆☆☆☆] 4db1c8f3bfa8e29f294f8581e8cccad6f5b3012387d53ef844f2de6fb9ef1fd6 流量包长度在“640-1279”之间的的数据包总共有多少&#xff1f;[答案&#xff1a;100][★☆☆☆☆] frame.len > 640…

智能时代中的工业应用中前所未有的灵活桥接和I/O扩展功能解决方案MachXO2系列LCMXO2-1200HC-4TG100I FPGA可编程逻辑IC

lattice莱迪斯 MachXO2系列LCMXO2-1200HC-4TG100I超低密度FPGA现场可编程门阵列&#xff0c;适用于低成本的复杂系统控制和视频接口设计开发&#xff0c;满足了通信、计算、工业、消费电子和医疗市场所需的系统控制和接口应用。 瞬时启动&#xff0c;迅速实现控制——启动时间…

23、区间和

区间和 题目描述 假定有一个无限长的数轴&#xff0c;数轴上每个坐标上的数都是0。 现在&#xff0c;我们首先进行 n 次操作&#xff0c;每次操作将某一位置x上的数加c。 接下来&#xff0c;进行 m 次询问&#xff0c;每个询问包含两个整数l和r&#xff0c;你需要求出在区间…

02-结构化程式与自定义函数

视频教程&#xff1a;b站视频【MATLAB教程_台大郭彦甫&#xff08;14课&#xff09;原视频补档】https://www.bilibili.com/video/BV1GJ41137UH/?share_sourcecopy_web&vd_sourc*ed6b9f96888e9c85118cb40c164875dfc 官网教程&#xff1a; MATLAB 快速入门 - MathWorks 中…

Java面试题戏剧

目录 第一幕 、第一场&#xff09;某大厦楼下大门前第二场&#xff09;电梯中第三场&#xff09;走廊中 第二幕、第一场&#xff09;公司前台第二场&#xff09;公司卫生间 第三幕、第一场&#xff09;一场异常面试 第四幕 、第一场&#xff09;大厦楼下门口第二场&#xff09;…

InternVideo2重塑视频理解新标杆,多模态学习引领行业风向

引言&#xff1a;视频理解的新篇章——InternVideo2的介绍 随着视频内容在日常生活中的普及&#xff0c;视频理解技术的重要性日益凸显。视频不仅包含丰富的视觉信息&#xff0c;还蕴含着动态变化和多模态元素&#xff0c;如音频和文本。这些特性使得视频成为一个复杂的数据类型…

【Python】科研代码学习:十七 模型参数合并,safetensors / bin

【Python】科研代码学习&#xff1a;十七 模型参数合并&#xff0c;safetensors / bin 前言解决代码知识点&#xff1a;safetensors 和 bin 的区别&#xff1f;知识点&#xff1a;save_pretrained 还会新增的文件知识点&#xff1a;在保存模型参数时&#xff0c;大小发生了成倍…