模型量化 - PTQ简史(一)

精炼模型

随着各类AI模型的高速发展,模型和深度学习系统的体量正在以指数级别逐渐膨胀。越发巨量的计算,存储,能耗等问题让AI从业者们迫不得已寻求对应的解决方案: 如何将巨大的AI模型适配在有

模型量化的一个本质是节约小数点。五年级数学课上,一个重要的问题是确定圆周率3.1415926约到第几位能做到方便估算。GPU等计算硬件同样需要简化小数。节约小数点位可以节省资源,圆周率节约到几位小数可以决定这种估算到底有多准确,模型量化也要面对这样的问题。是否模型量化后精简的模型和原来的模型达到相同的能力,量化-精度平衡

PTQ量化前身-OBS剪枝

模型剪枝是把模型裁剪部分权重的过程。1993年Hassibi 指出由于剪枝一个深度学习模型时造成的错误 Error相对于剪掉的权重w可以被泰勒展开模拟:

当一个神经网络的权重训练到局部最优或者聚合稳定状态时,上式的首项一阶导数即会无线趋近为零,但是第二项二阶导数不会为零,至于高阶导数,在泰勒展开模拟中往往都会被忽略。抹除具体某个w_q后,更新权重矩阵中其他值\delta w ,泰勒展开式第二项二阶因式(海森矩阵)的最小值,该最小值可由拉格朗日乘数法求得。

模型OBS压缩 = 剪枝 + 量化

Elias Frantar 他们使模型的剪枝和量化等价化。对于裁剪w - > 0 的过程只需要转换成量化 w - > quant(w)的过程。很明显,当quant(w) = 0,问题又回归到了权重裁剪。

他们另一个重要的工作是归纳并解决了Optimal Brain Surgeon算法复杂度上问题。原本得更新一层权重的海森矩阵d_{col}^2,求逆等过程将消耗\theta(d_{col}^3) 复杂度,落实到整个模型将会是将消耗 \theta(d_{col}^4)的复杂度,这对于现代模型来说是无法接受的。

取而代之使用cpu通过记录每一次造成最小错误\mathcal{L} = w_p^2/[H^{-1}]_{pp} 的位置,按所谓贪心的顺序记录一定次数,降低整体权重更新的计算复杂度。

通用Transformer模型量化

Elias 又一次提出了大体积模型基于OBS压缩的优化方案,他们重新审视了前面的方法中,针对超大体积多层transformer模型(GPT BLOOM)的实际效果。成功的达到了让超巨大模型的PTQ压缩在两个小时左右完成。

OBS压缩提到的按照最小错误 \mathcal{L} = w_p^2/[H^{-1}]_{pp} 的层位置依次更新单独那一层权重,这条原则对于大transformer模型来说毫无意义, 即便刚开始将错误值大的权重更新可能会产生额外的误差 \epsilon ,在后续更新其他值小\mathcal{L}时也会相应的把那些额外的误差\epsilon抵消。所以纵观量化中所有权重的过程不再遵循贪心顺序的原则,而是在确定层与层之间无关的情况下,任意顺序进行量化。

于是他们将按照每层的量化过程进一步优化成按照Batch(每N层)一起量化的过程。但一起量化对于大模型来说这个过程的中间计算量Hessian逆矩阵的计算容量要求异常巨大,于是设计了科列斯基分解的内核解决庞大中间值要求。

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch支持通过量化技术来压缩模型,减小模型大小和内存占用,并提高模型的推理性能。其中,PTQ(Post Training Quantization)是一种常见的量化方法,它可以在训练后对模型进行量化PTQ的基本思路是将原始模型中的浮点数参数转化为固定位宽的整数,从而减小模型的大小和内存占用,提高模型在嵌入式设备上的推理速度。在PTQ中,可以对权重、激活值、梯度等进行量化。 下面是使用PyTorch进行PTQ的基本流程: 1. 定义模型 首先需要定义一个PyTorch模型。 2. 定义量化方法 接下来需要定义量化方法。PyTorch提供了一些量化方法,可以根据实际需求进行选择。例如,可以使用torch.quantization.quantize_dynamic()方法进行动态量化,或者使用torch.quantization.quantize_static()方法进行静态量化。 3. 对模型进行量化 使用定义的量化方法对模型进行量化,将浮点数参数转化为整数参数。可以使用torch.quantization.prepare()方法对模型进行准备,使用torch.quantization.convert()方法进行转换。 4. 测试量化后的模型 量化完成后,需要测试量化后的模型,确保准确性没有明显下降。 下面是一个简单的示例代码,演示了如何使用PyTorch进行PTQ: ```python import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms from torchvision.models import resnet18 from torch.utils.data import DataLoader # 定义模型 model = resnet18() # 定义数据预处理 transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))]) # 加载数据集 trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform) trainloader = DataLoader(trainset, batch_size=128, shuffle=True) # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9) # 训练模型 for epoch in range(5): running_loss = 0.0 for i, data in enumerate(trainloader, 0): inputs, labels = data optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() print('[Epoch %d] loss: %.3f' % (epoch + 1, running_loss / len(trainloader))) # 定义量化方法 quantization_method = torch.quantization.quantize_dynamic # 对模型进行量化 model.qconfig = torch.quantization.get_default_qconfig('fbgemm') quantized_model = quantization_method(model, qconfig_spec={nn.Linear}, dtype=torch.qint8) # 测试量化后的模型 quantized_model.eval() testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform) testloader = DataLoader(testset, batch_size=128, shuffle=False) correct = 0 total = 0 with torch.no_grad(): for data in testloader: images, labels = data outputs = quantized_model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy of the network on the test images: %d %%' % (100 * correct / total)) ``` 注意:PTQ可能会对模型的准确性产生一定的影响,因此需要根据实际情况进行调整。同时,PTQ的效果也受到数据集的影响,因此需要在实际应用中进行测试和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值