量化是在微调之前还是之后进行更好?
作者:
Jambay Kinley, Sam Kemp2024年11月19日
👋 引言
机器学习中的量化是一种用于降低计算中数字精度的技术,有助于提高模型的效率。量化不是使用高精度浮点数(如32位或16位),而是将这些数字转换为低精度格式,例如8位整数。量化的主要优点是模型尺寸更小、计算速度更快,这对于在资源有限的设备(如手机或嵌入式系统)上部署模型特别有用。然而,这种精度降低有时可能会导致模型准确性略有下降。
使用LoRA(低秩适应)方法对AI模型进行微调是一种高效地将大型语言模型适应特定任务或领域的方式。LoRA不是重新训练所有模型参数,而是通过冻结原始模型权重并将更改应用于一组单独的权重来修改微调过程,然后将这些权重添加到原始参数中。这种方法将模型参数转换为较低的秩维度,减少了需要训练的参数数量,从而加快了过程并降低了成本。
在对模型进行微调和量化时,建立正确的顺序很重要。
- 量化是在微调**之前**进行更好,还是之后?
理论上,在微调之前进行量化应该能产生更好的模型,因为LoRA权重是使用它们将要部署的相同量化基础模型权重进行训练的。这避免了在浮点基础权重上训练然后使用量化基础模型部署时发生的精度损失。在这篇博文中,我们将展示Olive(ONNX Runtime 的尖端模型优化工具包)如何帮助您回答何时进行量化以及针对给定模型架构和场景使用哪种量化算法。
此外,作为回答何时进行量化问题的一部分,我们将展示以下不同的量化**算法**如何影响准确性:
- 激活感知权重量化 (AWQ) 是一种旨在优化大型语言模型 (LLM) 以实现高效执行的技术。AWQ 通过考虑推理过程中产生的激活来量化模型的权重。这意味着量化过程会考虑激活中实际的数据分布,与传统的权重量化方法相比,这有助于更好地保持模型准确性。
- 通用训练后量化 (GPTQ) 是一种专为生成式预训练 Transformer (GPT) 模型设计的训练后量化技术。它将模型的权重量化到较低的位宽,例如4位整数,以减少内存使用和计算需求,同时不显著影响模型的准确性。该技术独立量化权重矩阵的每一行,以找到一个误差最小的权重版本。
⚗️ 使用 Olive 运行实验
为了回答关于量化和微调正确顺序的问题,我们利用了 Olive (ONNX Live)——一个先进的模型优化工具包,旨在简化使用ONNX Runtime部署AI模型的优化过程。
注意:量化和微调都需要在 Nvidia A10 或 A100 GPU 机器上运行。
1. 💾 安装 Olive
我们使用 pip
安装了 Olive CLI。
pip install olive-ai[finetune]
pip install autoawq
pip install auto-gptq
2. 🗜️ 量化
我们使用以下 Olive 命令,通过 AWQ 和 GPTQ 算法对 Phi-3.5-mini-instruct 进行量化。
# AWQ Quantization
olive quantize \
--algorithm awq \
--model_name_or_path microsoft/Phi-3.5-mini-instruct \
--output_path models/phi-awq
# GPTQ Quantization
olive quantize \
--algorithm gptq \
--model_name_or_path microsoft/Phi-3.5-mini-instruct \
--data_name wikitext \
--subset wikitext-2-raw-v1 \
--split train \
--max_samples 128 \
--output_path models/phi-gptq
3. 🎚️ 微调
我们使用来自 Hugging Face 的 tiny codes 数据集对**量化后的模型**进行微调。这是一个受限数据集,您需要请求访问权限。获得访问权限后,您应该使用访问令牌登录 Hugging Face。
huggingface-clu login --token TOKEN
Olive 可以使用以下命令进行微调:
# Finetune AWQ model
olive finetune \
--model_name_or_path models/phi-awq \
--data_name nampdn-ai/tiny-codes \
--train_split "train[:4096]" \
--eval_split "train[4096:4224]" \
--text_template "### Language: {programming_language} \n### Question: {prompt} \n### Answer: {response}" \
--per_device_train_batch_size 16 \
--per_device_eval_batch_size 16 \
--max_steps 100 \
--logging_steps 25 \
--output_path models/phi-awq-ft
# Finetune GPTQ model
olive finetune \
--model_name_or_path models/phi-gptq \
--data_name nampdn-ai/tiny-codes \
--train_split "train[:4096]" \
--eval_split "train[4096:4224]" \
--text_template "### Language: {programming_language} \n### Question: {prompt} \n### Answer: {response}" \
--per_device_train_batch_size 16 \
--per_device_eval_batch_size 16 \
--max_steps 100 \
--logging_steps 25 \
--output_path models/phi-gptq-ft
注意:我们还进行了相反的顺序,即先微调再进行量化。它们是相同的命令,但执行顺序不同。
4. 🎯 运行困惑度评估
我们使用 Olive 对模型运行了困惑度指标评估。首先,我们在一个名为 perplexity-config.yaml
的文件中定义了以下 Olive 配置,该配置使用了 Olive 的评估功能。
input_model:
type: HfModel
model_path: models/phi-awq-ft/model
adapter_path: models/phi-awq-ft/adapter
systems:
local_system:
type: LocalSystem
accelerators:
- device: gpu
execution_providers:
- CUDAExecutionProvider
data_configs:
- name: tinycodes_ppl
type: HuggingfaceContainer
load_dataset_config:
data_name: nampdn-ai/tiny-codes
split: 'train[5000:6000]'
pre_process_data_config:
text_template: |-
### Language: {programming_language}
### Question: {prompt}
### Answer: {response}
strategy: line-by-line
max_seq_len: 1024
dataloader_config:
batch_size: 8
evaluators:
common_evaluator:
metrics:
- name: tinycodes_ppl
type: accuracy
sub_types:
- name: perplexity
data_config: tinycodes_ppl
passes: {}
auto_optimizer_config:
disable_auto_optimizer: true
evaluator: common_evaluator
host: local_system
target: local_system
output_dir: models/eval
注意:我们为其他模型定义了相同的配置,但更新了
input_model
。
然后,我们使用以下命令执行了 Olive 配置:
olive run --config perplexity-config.yaml
📊 结果
Phi-3.5-Mini-Instruct
下表显示了以下模型的困惑度指标:
- 不同的量化和微调顺序(品红色)
- Phi-3.5-Mini-Instruct 基础模型(绿色虚线),未量化
- Phi-3.5-Mini-Instruct 微调模型(绿色实线),未量化

目标是使量化模型尽可能接近微调模型(绿色实线)。有以下几点:
- 量化对模型质量没有显著影响——从量化模型的困惑度分数与微调基础模型的接近程度可以看出。
- 在微调**之前**进行量化确实比在微调之后进行量化能产生更好的结果。
- 在此场景中,GPTQ 提供了比 AWQ 更好的准确性。
Llama-3.1-8B-Instruct
下表显示了以下模型的困惑度指标:
- 不同的量化和微调顺序(蓝色)
- Llama-3.1-8B-Instruct 基础模型(绿色虚线),未量化
- Llama-3.1-8B-Instruct 微调模型(绿色实线),未量化

目标是使量化模型尽可能接近微调模型(绿色实线)。有以下几点:
- 量化对模型质量没有显著影响——从量化模型的困惑度分数与微调基础模型的接近程度可以看出。
- 在微调**之前**进行量化确实比在微调之后进行量化能产生更好的结果。
- GPTQ 和 AWQ 提供了相似的模型质量结果。
结论
在这篇博文中,我们展示了如何利用 Olive 来解决常见的 AI 模型优化问题。我们的研究结果表明,对于 Phi-3.5-mini-instruct 和 Llama-3.1-8B-Instruct,在微调之前进行量化可以提高模型质量。这些量化变体在内存和存储占用更少的情况下,其质量与全精度 (FP32) 对应版本非常接近。这强调了设备端 AI 在减少资源占用的同时提供高质量性能的潜力。