Optimum 文件
最佳化
並獲得增強的文件體驗
開始使用
最佳化
🤗 Optimum Intel 提供了一個 `openvino` 包,使您能夠使用 NNCF 框架對 🤗 Hub 上託管的許多模型應用各種模型量化方法。
量化是一種透過使用8位或4位等低精度資料型別表示權重和/或啟用來降低推理計算和記憶體成本的技術。
最佳化支援矩陣
點選 ✅ 即可複製相應最佳化情況的命令/程式碼。
| 任務 (OV 模型類別) | 僅權重 量化 | 混合量化 | 全量化 | 混合量化 | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 無資料 | 資料感知 | |||||||||
| CLI | Python | CLI | Python | CLI | Python | CLI | Python | CLI | Python | |
| 文字生成 (OVModelForCausalLM) | – | - | ||||||||
| 影像-文字-文字 (OVModelForVisualCausalLM) | – | – | – | – | ||||||
| 文字轉影像,文字轉影片 (OVDiffusionPipeline) | – | – | – | – | ||||||
| 自動語音識別 (OVModelForSpeechSeq2Seq) | – | – | – | – | – | – | – | – | ||
| 特徵提取 (OVModelForFeatureExtraction) | – | - | ||||||||
| 特徵提取 (OVSentenceTransformer) | – | - | ||||||||
| 填充遮罩 (OVModelForMaskedLM) | – | - | ||||||||
| 文字到文字生成 (OVModelForSeq2SeqLM) | – | - | ||||||||
| 零樣本影像分類 (OVModelForZeroShotImageClassification) | – | - | ||||||||
| 特徵提取 (OVSamModel) | – | – | – | - | – | – | ||||
| 文字到音訊 (OVModelForTextToSpeechSeq2Seq) | ✅ | – | – | – | – | – | – | – | – | |
僅權重 量化
量化可應用於模型的線性、卷積和嵌入層,從而在記憶體受限的裝置上載入大型模型。例如,當應用8位量化時,生成的模型將比其fp32模型小4倍。對於4位量化,記憶體的減少理論上可達到8倍,但實際中更接近6倍。
8位
對於8位權重量化,您可以將 `quantization_config` 設定為 `OVWeightQuantizationConfig(bits=8)` 以8位載入模型權重。
from optimum.intel import OVModelForCausalLM, OVWeightQuantizationConfig
model_id = "helenai/gpt2-ov"
quantization_config = OVWeightQuantizationConfig(bits=8)
model = OVModelForCausalLM.from_pretrained(model_id, quantization_config=quantization_config)
# Saves the int8 model that will be x4 smaller than its fp32 counterpart
model.save_pretrained(saving_directory)視覺語言流水線中的語言模型權重可以以類似方式進行量化
model = OVModelForVisualCausalLM.from_pretrained(
"llava-hf/llava-v1.6-mistral-7b-hf",
quantization_config=quantization_config
)如果未提供 `quantization_config`,並且模型引數超過10億,則預設以8位匯出模型。您可以透過 `load_in_8bit=False` 停用此功能。
4位
4位權重量化可以以類似的方式實現
from optimum.intel import OVModelForCausalLM, OVWeightQuantizationConfig
quantization_config = OVWeightQuantizationConfig(bits=4)
model = OVModelForCausalLM.from_pretrained(model_id, quantization_config=quantization_config)或者用於視覺-語言流水線
model = OVModelForVisualCausalLM.from_pretrained(
"llava-hf/llava-v1.6-mistral-7b-hf",
quantization_config=quantization_config
)您可以調整量化引數以實現更好的效能精度權衡,如下所示
quantization_config = OVWeightQuantizationConfig(
bits=4,
sym=False,
ratio=0.8,
quant_method="awq",
dataset="wikitext2"
)注意:`OVWeightQuantizationConfig` 也接受未列在其建構函式中的關鍵字引數。在這種情況下,這些引數將直接傳遞給 `nncf.compress_weights()` 呼叫。這對於將附加引數傳遞給量化演算法很有用。
預設情況下,量化方案將是非對稱的,要使其對稱,您可以新增 `sym=True`。
對於4位量化,您還可以在量化配置中指定以下引數
- `group_size` 引數將定義用於量化的組大小,`-1` 將導致按列量化。
- `ratio` 引數控制4位和8位量化之間的比率。如果設定為0.9,則表示90%的層將被量化為`int4`,而10%將被量化為`int8`。
較小的 `group_size` 和 `ratio` 值通常會提高精度,但會犧牲模型大小和推理延遲。
4位權重壓縮模型的質量可以透過採用以下資料依賴方法之一進一步提高
- **AWQ**,即“啟用感知量化”(Activation Aware Quantization),是一種用於調整模型權重以實現更精確的4位壓縮的演算法。它略微提高了壓縮LLM的生成質量,但需要在校準資料集上進行權重調整,耗費大量額外時間和記憶體。請注意,模型中可能不存在適用於AWQ的匹配模式,在這種情況下它將被跳過。還有一種無需資料的AWQ版本,它依賴於權重的每列幅度而不是啟用。
- **尺度估計**是一種調整量化尺度以最小化原始層和壓縮層之間L2誤差的方法。需要提供資料集才能執行尺度估計。使用此方法還會產生額外的時間和記憶體開銷。
- **GPTQ** 以逐層方式最佳化壓縮權重,以最小化壓縮層和原始層啟用之間的差異。
- **LoRA Correction** 透過利用低秩適應來緩解權重壓縮過程中引入的量化噪聲。
資料感知演算法可以同時或單獨應用。為此,請向4位 `OVWeightQuantizationConfig` 提供相應的引數以及資料集。例如
quantization_config = OVWeightQuantizationConfig(
bits=4,
sym=False,
ratio=0.8,
quant_method="awq",
scale_estimation=True,
gptq=True,
dataset="wikitext2"
)注意:GPTQ 和 LoRA Correction 演算法不能同時應用。
全量化
在應用訓練後全量化時,權重和啟用都將被量化。要對啟用應用量化,需要額外的校準步驟,該步驟包括向網路提供 `calibration_dataset` 以估計量化啟用引數。
以下是如何在您自己的 `calibration_dataset` 上對微調後的 DistilBERT 應用全量化
from transformers import AutoTokenizer
from optimum.intel import OVQuantizer, OVModelForSequenceClassification, OVConfig, OVQuantizationConfig
model_id = "distilbert-base-uncased-finetuned-sst-2-english"
model = OVModelForSequenceClassification.from_pretrained(model_id, export=True)
tokenizer = AutoTokenizer.from_pretrained(model_id)
# The directory where the quantized model will be saved
save_dir = "ptq_model"
quantizer = OVQuantizer.from_pretrained(model)
# Apply full quantization and export the resulting quantized model to OpenVINO IR format
ov_config = OVConfig(quantization_config=OVQuantizationConfig())
quantizer.quantize(ov_config=ov_config, calibration_dataset=calibration_dataset, save_directory=save_dir)
# Save the tokenizer
tokenizer.save_pretrained(save_dir)校準資料集也可以使用您的 `OVQuantizer` 輕鬆建立
from functools import partial
def preprocess_function(examples, tokenizer):
return tokenizer(examples["sentence"], padding="max_length", max_length=128, truncation=True)
# Create the calibration dataset used to perform full quantization
calibration_dataset = quantizer.get_calibration_dataset(
"glue",
dataset_config_name="sst2",
preprocess_function=partial(preprocess_function, tokenizer=tokenizer),
num_samples=300,
dataset_split="train",
)`quantize()` 方法應用訓練後量化並將生成的量化模型匯出到 OpenVINO 中間表示 (IR)。生成的圖由兩個檔案表示:描述網路拓撲的 XML 檔案和描述權重的二進位制檔案。生成的模型可以在任何目標 Intel 裝置上執行。
語音轉文字模型量化
語音轉文字的 Whisper 模型可以在不需要準備自定義校準資料集的情況下進行量化。請參閱下面的示例。
model_id = "openai/whisper-tiny"
ov_model = OVModelForSpeechSeq2Seq.from_pretrained(
model_id,
quantization_config=OVQuantizationConfig(
num_samples=10,
dataset="librispeech",
processor=model_id,
matmul_sq_alpha=0.95,
)
)透過這種方式,Whisper 流水線的編碼器、解碼器和帶past的解碼器模型將被完全量化,包括啟用。
混合量化
傳統的最佳化方法,如訓練後8位量化,對穩定擴散(SD)模型效果不佳,可能導致生成結果不理想。另一方面,權重壓縮在應用於穩定擴散模型時並不能顯著提高效能,因為啟用的大小與權重相當。U-Net 元件佔據了流水線整體執行時間的大部分。因此,僅最佳化這一個元件可以在推理速度方面帶來顯著的好處,同時在不進行微調的情況下保持可接受的精度。量化擴散流水線的其餘部分並不能顯著提高推理效能,但可能會導致精度大幅下降。因此,建議對 U-Net 模型應用混合模式量化,並對流水線其餘元件應用僅權重量化。
- U-Net:對權重和啟用都應用量化
- 文字編碼器、VAE 編碼器/解碼器:對權重應用量化
混合模式涉及MatMul和Embedding層中權重的量化,以及其他層中啟用的量化,這有助於在最佳化後保持精度,同時減小模型大小。
`quantization_config` 用於定義最佳化SD流水線的最佳化引數。要啟用混合量化,請在 `quantization_config` 中指定量化資料集。如果未定義資料集,則所有元件都將應用僅權重(weight-only)量化。
from optimum.intel import OVStableDiffusionPipeline, OVWeightQuantizationConfig
model = OVStableDiffusionPipeline.from_pretrained(
model_id,
export=True,
quantization_config=OVWeightQuantizationConfig(bits=8, dataset="conceptual_captions"),
)更多詳情請參閱相應的NNCF 文件。
混合量化
混合量化是一種將僅權重(weight-only)量化與完全量化結合的技術。在混合量化過程中,我們分別量化
- 加權層的權重到一種精度,以及
- 其他支援層的啟用(可能還有權重,如果有些在第一步被跳過)到另一種精度。
預設情況下,所有加權層的權重都在第一步中進行量化。在第二步中,加權層和非加權層的啟用都將被量化。如果在第一步中,某些層透過 `weight_quantization_config.ignored_scope` 引數被指示忽略,則這些層的權重和啟用都將量化到 `full_quantization_config` 中給定的精度。
透過 Python API 執行此類最佳化時,應使用 `OVMixedQuantizationConfig`。在這種情況下,第一步的精度應透過 `weight_quantization_config` 引數提供,第二步的精度應透過 `full_quantization_config` 引數提供。例如
model = OVModelForCausalLM.from_pretrained(
'TinyLlama/TinyLlama-1.1B-Chat-v1.0',
quantization_config=OVMixedQuantizationConfig(
weight_quantization_config=OVWeightQuantizationConfig(bits=4, dtype='nf4'),
full_quantization_config=OVQuantizationConfig(dtype='f8e4m3', dataset='wikitext2')
)
)要透過 CLI 應用混合量化,應使用 `--quant-mode` 引數。例如
optimum-cli export openvino -m TinyLlama/TinyLlama-1.1B-Chat-v1.0 --quant-mode nf4_f8e4m3 --dataset wikitext2 ./save_dir別忘了提供資料集,因為全量化校準過程需要它。
流水線量化
存在由多個元件組成的多模態流水線,例如穩定擴散或視覺語言模型。在這些情況下,可能需要對流水線的不同元件應用不同的量化方法。例如,您可能希望對視覺語言流水線中的語言模型應用 int4 資料感知僅權重(data-aware weight-only)量化,而對其他元件應用 int8 僅權重(weight-only)量化。在這種情況下,您可以使用 `OVPipelineQuantizationConfig` 類來為流水線的每個元件指定量化配置。
例如,以下程式碼量化了 InternVL2-1B 中語言模型的權重和啟用,壓縮了文字嵌入模型的權重,並跳過了視覺嵌入模型的任何量化。
from optimum.intel import OVModelForVisualCausalLM
from optimum.intel import OVPipelineQuantizationConfig, OVQuantizationConfig, OVWeightQuantizationConfig
model_id = "OpenGVLab/InternVL2-1B"
model = OVModelForVisualCausalLM.from_pretrained(
model_id,
export=True,
trust_remote_code=True,
quantization_config=OVPipelineQuantizationConfig(
quantization_configs={
"lm_model": OVQuantizationConfig(bits=8),
"text_embeddings_model": OVWeightQuantizationConfig(bits=8),
},
dataset="contextual",
trust_remote_code=True,
)
)