Transformers 4.37 中文文档(八)(4)

简介: Transformers 4.37 中文文档(八)

Transformers 4.37 中文文档(八)(3)https://developer.aliyun.com/article/1563210


bitsandbytes

bitsandbytes是将模型量化为 8 位和 4 位的最简单选择。8 位量化将 fp16 中的异常值与 int8 中的非异常值相乘,将非异常值转换回 fp16,然后将它们相加以返回 fp16 中的权重。这减少了异常值对模型性能的降级影响。4 位量化进一步压缩模型,通常与QLoRA一起用于微调量化的 LLM。

要使用 bitsandbytes,请确保已安装以下库:

8 位 4 位

pip install transformers accelerate bitsandbytes>0.37.0

现在您可以使用 from_pretrained()方法中的load_in_8bitload_in_4bit参数来量化模型。只要模型支持使用 Accelerate 加载并包含torch.nn.Linear层,这对任何模态的模型都适用。

8 位 4 位

将模型量化为 8 位可以减半内存使用量,对于大型模型,设置device_map="auto"以有效地使用可用的 GPU:

from transformers import AutoModelForCausalLM
model_8bit = AutoModelForCausalLM.from_pretrained("bigscience/bloom-1b7", device_map="auto", load_in_8bit=True)

默认情况下,所有其他模块(如torch.nn.LayerNorm)都会转换为torch.float16。如果需要,您可以使用torch_dtype参数更改这些模块的数据类型:

import torch
from transformers import AutoModelForCausalLM
model_8bit = AutoModelForCausalLM.from_pretrained("facebook/opt-350m", load_in_8bit=True, torch_dtype=torch.float32)
model_8bit.model.decoder.layers[-1].final_layer_norm.weight.dtype

一旦模型被量化为 8 位,除非您使用最新版本的 Transformers 和 bitsandbytes,否则无法将量化的权重推送到  Hub。如果您有最新版本,则可以使用 push_to_hub()方法将 8 位模型推送到 Hub。首先推送量化的 config.json  文件,然后是量化的模型权重。

from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("bigscience/bloom-560m", device_map="auto", load_in_8bit=True)
tokenizer = AutoTokenizer.from_pretrained("bigscience/bloom-560m")
model.push_to_hub("bloom-560m-8bit")

仅支持使用 8 位和 4 位权重进行训练额外参数。

您可以使用get_memory_footprint方法检查内存占用情况:

print(model.get_memory_footprint())

可以从 from_pretrained()方法中加载量化模型,无需指定load_in_8bitload_in_4bit参数:

from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("{your_username}/bloom-560m-8bit", device_map="auto")

8 位

在这篇博客文章中了解更多关于 8 位量化的细节!

本节探讨了 8 位模型的一些特定功能,如转移、异常值阈值、跳过模块转换和微调。

转移

8 位模型可以在 CPU 和 GPU 之间转移权重,以支持将非常大的模型适配到内存中。发送到 CPU 的权重实际上是以float32存储的,并且不会转换为 8 位。例如,要为bigscience/bloom-1b7模型启用转移,请首先创建一个 BitsAndBytesConfig:

from transformers import AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(llm_int8_enable_fp32_cpu_offload=True)

设计一个自定义设备映射,将所有内容都适配到 GPU 上,除了lm_head,这部分将发送到 CPU:

device_map = {
    "transformer.word_embeddings": 0,
    "transformer.word_embeddings_layernorm": 0,
    "lm_head": "cpu",
    "transformer.h": 0,
    "transformer.ln_f": 0,
}

现在使用自定义的device_mapquantization_config加载您的模型:

model_8bit = AutoModelForCausalLM.from_pretrained(
    "bigscience/bloom-1b7",
    device_map=device_map,
    quantization_config=quantization_config,
)
异常值阈值

“异常值”是大于某个阈值的隐藏状态值,这些值是在 fp16 中计算的。虽然这些值通常是正态分布的([-3.5,  3.5]),但对于大型模型([-60, 6]或[6, 60]),这种分布可能会有很大不同。8 位量化适用于值约为  5,但超过这个值,会有显著的性能损失。一个很好的默认阈值是 6,但对于更不稳定的模型(小模型或微调),可能需要更低的阈值。

为了找到您的模型的最佳阈值,我们建议尝试在 BitsAndBytesConfig 中使用llm_int8_threshold参数进行实验:

from transformers import AutoModelForCausalLM, BitsAndBytesConfig
model_id = "bigscience/bloom-1b7"
quantization_config = BitsAndBytesConfig(
    llm_int8_threshold=10,
)
model_8bit = AutoModelForCausalLM.from_pretrained(
    model_id,
    device_map=device_map,
    quantization_config=quantization_config,
)
跳过模块转换

对于一些模型,如 Jukebox,您不需要将每个模块量化为 8 位,这实际上可能会导致不稳定性。对于 Jukebox,有几个lm_head模块应该使用 BitsAndBytesConfig 中的llm_int8_skip_modules参数跳过:

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
model_id = "bigscience/bloom-1b7"
quantization_config = BitsAndBytesConfig(
    llm_int8_skip_modules=["lm_head"],
)
model_8bit = AutoModelForCausalLM.from_pretrained(
    model_id,
    device_map="auto",
    quantization_config=quantization_config,
)
微调

使用PEFT库,您可以使用 8 位量化微调大型模型,如flan-t5-largefacebook/opt-6.7b。在训练时不需要传递device_map参数,因为它会自动将您的模型加载到 GPU 上。但是,如果您想要,仍然可以使用device_map参数自定义设备映射(device_map="auto"仅应用于推断)。

4 位

在这个notebook中尝试 4 位量化,并在这篇博客文章中了解更多细节。

本节探讨了 4 位模型的一些特定功能,如更改计算数据类型、使用 Normal Float 4 (NF4)数据类型和使用嵌套量化。

计算数据类型

为了加速计算,您可以将数据类型从 float32(默认值)更改为 bf16,使用 BitsAndBytesConfig 中的bnb_4bit_compute_dtype参数:

import torch
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16)
Normal Float 4 (NF4)

NF4 是来自QLoRA论文的 4 位数据类型,适用于从正态分布初始化的权重。您应该使用 NF4 来训练 4 位基础模型。这可以通过 BitsAndBytesConfig 中的bnb_4bit_quant_type参数进行配置:

from transformers import BitsAndBytesConfig
nf4_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
)
model_nf4 = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=nf4_config)

对于推断,bnb_4bit_quant_type对性能没有太大影响。但是,为了保持与模型权重一致,您应该使用bnb_4bit_compute_dtypetorch_dtype值。

嵌套量化

嵌套量化是一种技术,可以在不增加性能成本的情况下节省额外的内存。此功能对已经量化的权重执行第二次量化,以节省额外的 0.4 位/参数。例如,使用嵌套量化,您可以在 16GB 的 NVIDIA T4 GPU 上微调Llama-13b模型,序列长度为 1024,批量大小为 1,并启用梯度累积 4 步。

from transformers import BitsAndBytesConfig
double_quant_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_use_double_quant=True,
)
model_double_quant = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-13b", quantization_config=double_quant_config)

Optimum

Optimum库支持  Intel、Furiosa、ONNX Runtime、GPTQ 和较低级别的 PyTorch 量化功能。如果您正在使用像 Intel  CPU、Furiosa NPU 或像 ONNX Runtime 这样的模型加速器这样的特定和优化的硬件,请考虑使用 Optimum 进行量化。

基准测试

要比较每种量化方案的速度、吞吐量和延迟,请查看从optimum-benchmark库获得的以下基准测试。该基准测试在 NVIDIA A1000 上运行,用于TheBloke/Mistral-7B-v0.1-AWQTheBloke/Mistral-7B-v0.1-GPTQ模型。这些还与 bitsandbytes 量化方法以及本机 fp16 模型进行了测试。

前向峰值内存/批处理大小

每批生成峰值内存/批处理大小

每批生成吞吐量/批处理大小

前向延迟/批处理大小

基准测试表明,AWQ 量化在推理、文本生成方面是最快的,并且在文本生成方面具有最低的峰值内存。然而,AWQ 在每个批处理大小上具有最大的前向延迟。要了解每种量化方法的优缺点的更详细讨论,请阅读🤗 Transformers 中本地支持的量化方案概述博客文章。

融合 AWQ 模块

TheBloke/Mistral-7B-OpenOrca-AWQ模型在batch_size=1下进行了基准测试,有无融合模块。

未融合模块

批处理大小 预填充长度 解码长度 预填充标记/秒 解码标记/秒 内存(VRAM)
1 32 32 60.0984 38.4537 4.50 GB (5.68%)
1 64 64 1333.67 31.6604 4.50 GB (5.68%)
1 128 128 2434.06 31.6272 4.50 GB (5.68%)
1 256 256 3072.26 38.1731 4.50 GB (5.68%)
1 512 512 3184.74 31.6819 4.59 GB (5.80%)
1 1024 1024 3148.18 36.8031 4.81 GB (6.07%)
1 2048 2048 2927.33 35.2676 5.73 GB (7.23%)

融合模块

批处理大小 预填充长度 解码长度 预填充标记/秒 解码标记/秒 内存(VRAM)
1 32 32 81.4899 80.2569 4.00 GB (5.05%)
1 64 64 1756.1 106.26 4.00 GB (5.05%)
1 128 128 2479.32 105.631 4.00 GB (5.06%)
1 256 256 1813.6 85.7485 4.01 GB (5.06%)
1 512 512 2848.9 97.701 4.11 GB (5.19%)
1 1024 1024 3044.35 87.7323 4.41 GB (5.57%)
1 2048 2048 2715.11 89.4709 5.57 GB (7.04%)

融合和未融合模块的速度和吞吐量也经过了optimum-benchmark库的测试。

前向峰值内存/批处理大小

每批生成吞吐量/批处理大小


Transformers 4.37 中文文档(八)(5)https://developer.aliyun.com/article/1563212

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
3月前
|
数据可视化 自动驾驶 机器人
Transformers 4.37 中文文档(五)(4)
Transformers 4.37 中文文档(五)
36 0
|
3月前
|
数据可视化 PyTorch TensorFlow
Transformers 4.37 中文文档(四)(4)
Transformers 4.37 中文文档(四)
28 1
Transformers 4.37 中文文档(四)(4)
|
3月前
|
自然语言处理 PyTorch TensorFlow
Transformers 4.37 中文文档(一)(2)
Transformers 4.37 中文文档(一)
66 1
|
3月前
|
自然语言处理 PyTorch TensorFlow
Transformers 4.37 中文文档(一百)(4)
Transformers 4.37 中文文档(一百)
40 1
|
3月前
|
自然语言处理 PyTorch TensorFlow
Transformers 4.37 中文文档(一百)(5)
Transformers 4.37 中文文档(一百)
28 1
|
3月前
|
自然语言处理 PyTorch TensorFlow
Transformers 4.37 中文文档(一百)(6)
Transformers 4.37 中文文档(一百)
30 1
|
3月前
|
存储 API 计算机视觉
Transformers 4.37 中文文档(五)(2)
Transformers 4.37 中文文档(五)
40 1
|
3月前
|
PyTorch TensorFlow 算法框架/工具
Transformers 4.37 中文文档(四)(3)
Transformers 4.37 中文文档(四)
30 1
|
3月前
|
PyTorch TensorFlow 调度
Transformers 4.37 中文文档(四)(2)
Transformers 4.37 中文文档(四)
47 1
|
3月前
|
并行计算 测试技术 TensorFlow
Transformers 4.37 中文文档(八)(3)
Transformers 4.37 中文文档(八)
48 2