基于Transformer的扩散模型正日益完善,并已被证明能够彻底改变文本到图像的生成模式。Transformer的能力提升了任何模型的可扩展性和性能,同时也增加了模型的复杂性。
"能力越强,责任越大"
在这种情况下,模型复杂性越高,功耗和内存消耗也越大。
例如,使用像Stable Diffusion 3这样的模型运行推理需要巨大的GPU内存,因为它涉及多个组件——文本编码器、扩散主干网络和图像解码器。这种高内存需求给使用消费级GPU的用户带来了阻碍,影响了可访问性和实验性。
模型量化技术应运而生。想象一下,将一个资源密集型模型缩小到更易于管理的大小,同时又不牺牲其有效性。量化就像将高分辨率图像压缩成更紧凑的格式,将模型的参数转换为更低精度的表示形式。这不仅减少了内存使用,还加速了计算,使复杂模型更易于访问和使用。
本文将探讨Quanto的量化工具如何显著提升基于Transformer的扩散 pipeline 的内存效率。
量化是降低深度学习模型计算和内存需求的关键技术,使其更适合在消费类设备上部署。通过使用低精度数据类型(如8位整数)代替32位浮点数,量化不仅减少了内存存储需求,还能针对特定硬件(如CUDA设备上的int8或float8矩阵乘法)进行优化。
Quanto是Optimum的一个新的量化后端,旨在提供一个通用且直接的量化过程。Quanto因其对各种功能的全面支持而脱颖而出,确保了与多样化模型配置和设备的兼容性:
虽然许多工具专注于使大型AI模型变小,但Quanto旨在对所有类型的模型都简单实用。
使用pip安装Quanto,请使用以下代码:
!pip install optimum-quanto量化模型
以下代码将帮助将标准模型转换为量化模型:
from optimum.quanto import quantize, qint8
quantize(model, weights=qint8, activations=qint8)校准
Quanto的校准模式确保量化参数根据模型中的实际数据分布进行调整,从而提高量化模型的准确性和效率。
from optimum.quanto import Calibration
with Calibration(momentum=0.9):
model(samples)量化感知训练
如果模型性能受到影响,可以对模型进行几个epoch的微调以提升性能。
import torch
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()冻结整数权重
冻结模型时,浮点权重将转换为量化权重。
from optimum.quanto import freeze
freeze(model)某机构的H100 GPU是一款专为处理要求苛刻的AI任务而设计的高性能显卡,包括用于大型模型(如Transformer和扩散模型)的训练和推理。选择它进行基准测试的原因如下:
在基准测试研究中,主要关注点是应用Quanto这种新的量化工具于扩散模型。虽然量化在大型语言模型从业者中众所周知,但在扩散模型中并不常用。本研究使用Quanto来探索它是否能在质量几乎没有损失的情况下,为这些模型节省内存。
研究内容如下:
环境设置
通过使用H100 GPU并专注于这些关键模型,本研究旨在展示Quanto在弥合LLM和扩散模型之间量化差距方面的潜力,提供显著的内存节省,同时对性能的影响最小。
使用Quanto量化模型遵循一个简单的过程:
首先安装所需的包,此处安装transformers、quanto、torch、sentencepiece。但请注意,可能需要根据要求安装更多包。
!pip install transformers==4.35.0
!pip install quanto==0.0.11
!pip install torch==2.1.1
!pip install sentencepiece==0.2.0
!pip install optimum-quanto在被量化的模块上调用quantize()函数,指定要量化的目标组件。在此上下文中,只有参数被量化,而激活函数保持不变。参数被量化为FP8数据类型。最后,调用freeze()函数,用新量化的参数替换原始参数。
from optimum.quanto import freeze, qfloat8, quantize
from diffusers import PixArtSigmaPipeline
import torch
pipeline = PixArtSigmaPipeline.from_pretrained(
"PixArt-alpha/PixArt-Sigma-XL-2-1024-MS", torch_dtype=torch.float16
).to("cuda")
quantize(pipeline.transformer, weights=qfloat8)
freeze(pipeline.transformer)完成后使用pipeline。
image = pipeline("ghibli风格,一个带有城堡的幻想景观").images[0](使用FP8扩散Transformer生成的图像)
以下代码可用于量化文本编码器:
quantize(pipeline.text_encoder, weights=qfloat8)
freeze(pipeline.text_encoder)文本编码器本身也是一个Transformer模型,因此也可以进行量化。通过量化文本编码器和扩散主干网络,可以获得更大的内存节省。
LLM Pipelines
optimum-quanto提供了辅助类来量化、保存和重新加载某机构的量化模型。
下面的代码将使用Transformers库加载预训练语言模型(Meta-Llama-3-8B)。然后,它使用Optimum Quanto中的QuantizedModelForCausalLM类对模型应用量化,特别将模型的权重转换为qint4数据类型。lm_head(输出层)被排除在量化之外以保持其精度,确保最终输出质量保持高水平。
from transformers import AutoModelForCausalLM
from optimum.quanto import QuantizedModelForCausalLM, qint4
model = AutoModelForCausalLM.from_pretrained('某机构/Meta-Llama-3-8B')
qmodel = QuantizedModelForCausalLM.quantize(model, weights=qint4, exclude='lm_head')# 可以使用 save_pretrained 保存量化模型
qmodel.save_pretrained('./Llama-3-8B-quantized')# 使用 from_pretrained 重新加载模型
from optimum.quanto import QuantizedModelForCausalLM
qmodel = QuantizedModelForCausalLM.from_pretrained('Llama-3-8B-quantized')与Transformers的集成
Quanto与某机构的transformers库无缝集成。只需通过QuantoConfig传递模型,即可对任何模型进行量化。
from transformers import AutoModelForCausalLM, AutoTokenizer, QuantoConfig
model_id = "某机构/opt-125m"
tokenizer = AutoTokenizer.from_pretrained(model_id)
quantization_config = QuantoConfig(weights="int8")
quantized_model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config= quantization_config
)使用Quanto,无论在CPU/GPU/MPS上,都可以量化和运行模型。
from transformers import AutoModelForSpeechSeq2Seq
model_id = "某机构/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
)这种设置使模型变得更小、更快,同时仍保持良好的准确性水平。
在扩散模型中量化文本编码器(例如Stable Diffusion中使用的编码器)会显著影响性能和内存效率。对于使用三个不同文本编码器的Stable Diffusion 3,关于量化这些编码器的观察结果如下:
在内存节省方面,下表详细说明了应用每种量化策略可以节省多少内存,特别关注量化不同文本编码器组合的相对优势和权衡。
qint8由于高效的整数运算和硬件优化,通常推理速度更快。int8内核,通过减少操作次数和利用高效数据处理进一步优化计算。qint4与bfloat16结合时,内存使用有所改善,因为qint4每个值仅使用4位,减少了存储权重所需的内存量。然而,这是以增加推理延迟为代价的。这是因为H100 GPU仍然不支持4位整数的计算。尽管权重以压缩的4位格式存储,但实际计算仍以bfloat16执行,这意味着硬件必须处理更复杂的操作,导致处理时间变慢。Quanto为PyTorch提供了一个强大的量化后端,通过将权重转换为更低精度的格式来优化模型性能。通过支持qint8和qint4等技术,Quanto减少了内存消耗并加速了推理。此外,Quanto可跨不同设备工作,并与各种设置兼容。但在MPS设备上,使用float8会导致错误。
总体而言,Quanto实现了深度学习模型更高效的部署,在内存节省和性能权衡之间取得了平衡。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。