# 模型量化

## `bitsandbytes` 集成

Accelerate 将 `bitsandbytes` 量化功能引入你的模型。现在，你只需几行代码即可将任意 PyTorch 模型以 8 位或 4 位加载。

如果您想使用 `bitsandbytes` 来使用 Transformers 模型，请遵循此[文档](https://huggingface.co/docs/transformers/main_classes/quantization)。

要了解 `bitsandbytes` 量化的工作原理，请阅读有关 [8 位量化](https://huggingface.co/blog/hf-bitsandbytes-integration) 和 [4 位量化](https://huggingface.co/blog/4bit-transformers-bitsandbytes) 的博文。

### 先决条件
您需要安装以下依赖项：

- 安装 `bitsandbytes` 库
```bash
pip install bitsandbytes
```
对于非 cuda 设备，您可以参考 [此处](https://huggingface.co/docs/bitsandbytes/main/en/installation#multi-backend) 的 bitsandbytes 安装指南。

- 从源代码安装最新的 `accelerate`
```bash
pip install git+https://github.com/huggingface/accelerate.git
```
- 安装 `minGPT` 和 `huggingface_hub` 以运行示例
```bash
git clone https://github.com/karpathy/minGPT.git
pip install minGPT/
pip install huggingface_hub
```

### 工作原理

首先，我们需要初始化模型。为了节省内存，我们可以使用上下文管理器 [init_empty_weights()](/docs/accelerate/main/zh/package_reference/big_modeling#accelerate.init_empty_weights) 来初始化一个空模型。

让我们以 minGPT 库中的 GPT2 模型为例。
```py
from accelerate import init_empty_weights
from mingpt.model import GPT

model_config = GPT.get_default_config()
model_config.model_type = 'gpt2-xl'
model_config.vocab_size = 50257
model_config.block_size = 1024

with init_empty_weights():
    empty_model = GPT(model_config)
```

然后，我们需要获取模型权重的路径。该路径可以是 state_dict 文件（例如 "pytorch_model.bin"），也可以是包含分片检查点的文件夹。

```py
from huggingface_hub import snapshot_download
weights_location = snapshot_download(repo_id="marcsun13/gpt2-xl-linear-sharded")
```

最后，您需要使用 [BnbQuantizationConfig](/docs/accelerate/main/zh/package_reference/utilities#accelerate.utils.BnbQuantizationConfig) 来设置量化配置。

以下是 8 位量化的示例：
```py
from accelerate.utils import BnbQuantizationConfig
bnb_quantization_config = BnbQuantizationConfig(load_in_8bit=True, llm_int8_threshold = 6)
```

以下是 4 位量化的示例：
```py
from accelerate.utils import BnbQuantizationConfig
bnb_quantization_config = BnbQuantizationConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16, bnb_4bit_use_double_quant=True, bnb_4bit_quant_type="nf4")
```

若要使用所选配置对空模型进行量化，您需要使用 [load_and_quantize_model()](/docs/accelerate/main/zh/package_reference/utilities#accelerate.utils.load_and_quantize_model)。

```py
from accelerate.utils import load_and_quantize_model
quantized_model = load_and_quantize_model(empty_model, weights_location=weights_location, bnb_quantization_config=bnb_quantization_config)
```

### 保存和加载 8 位模型

您可以使用 [save_model()](/docs/accelerate/main/zh/package_reference/accelerator#accelerate.Accelerator.save_model) 通过 accelerate 保存您的 8 位模型。

```py
from accelerate import Accelerator
accelerate = Accelerator()
new_weights_location = "path/to/save_directory"
accelerate.save_model(quantized_model, new_weights_location)

quantized_model_from_saved = load_and_quantize_model(empty_model, weights_location=new_weights_location, bnb_quantization_config=bnb_quantization_config, device_map = "auto")
```

请注意，目前不支持 4 位模型序列化。

### 将模块卸载到 cpu 和磁盘 

如果 GPU 空间不足以将整个模型存储在 GPU 上，您可以将部分模块卸载到 cpu/disk。这会在底层使用大模型推理。有关更多详细信息，请参阅此[文档](https://huggingface.co/docs/accelerate/usage_guides/big_modeling)。

对于 8 位量化，所选模块将被转换为 8 位精度。

对于 4 位量化，所选模块将保留为用户在 `BnbQuantizationConfig` 中传入的 `torch_dtype`。当 4 位序列化成为可能时，我们将添加支持，以便在 4 位下转换这些已卸载的模块。

 您只需传入自定义的 `device_map` 即可将模块卸载到 CPU/磁盘。这些被卸载的模块会在需要时调度到 GPU 上。以下是一个示例：

```py
device_map = {
    "transformer.wte": 0,
    "transformer.wpe": 0,
    "transformer.drop": 0,
    "transformer.h": "cpu",
    "transformer.ln_f": "disk",
    "lm_head": "disk",
}
```
### 微调量化模型

无法在这些模型上执行纯 8 位或 4 位训练。不过，您可以利用参数高效微调方法（PEFT）来训练这些模型，例如在模型之上训练适配器。有关更多详细信息，请参阅 [peft](https://github.com/huggingface/peft) 库。

目前，您无法在任何量化模型之上添加适配器。不过，借助 Transformers 模型对适配器的官方支持，您可以对量化模型进行微调。如果您想微调一个 Transformers 模型，请改为遵循此[文档](https://huggingface.co/docs/transformers/main_classes/quantization)。查看此[演示](https://colab.research.google.com/drive/1VoYNfYDKcKRQRor98Zbf2-9VQTtGJ24k?usp=sharing)，了解如何微调一个 4 位 Transformers 模型。

请注意，在加载模型进行训练时，您无需传入 `device_map`。它会自动将模型加载到您的 GPU 上。请注意，`device_map=auto` 仅应用于推理。

### 示例演示 - 在 Google Colab 上运行 GPT2 1.5b

查看 Google Colab [演示](https://colab.research.google.com/drive/1T1pOgewAWVpR9gKpaEWw4orOrzPFb3yM?usp=sharing)，了解如何在 GPT2 模型上运行量化模型。GPT2-1.5B 模型检查点采用 FP32 格式，占用 6GB 内存。量化后，使用 8 位模块时占用 1.6GB，使用 4 位模块时占用 1.2GB。

