Skip to main content

使用 Intel Transformers 扩展 Pipeline 对 Hugging Face 模型进行仅权重量化

Hugging Face 模型可以通过 WeightOnlyQuantPipeline 类在本地使用仅权重量化运行。 Hugging Face 模型中心托管了超过 12 万个模型、2 万个数据集和 5 万个演示应用(Spaces),全部开源并公开可用,在一个在线平台上供人们轻松协作共同构建 ML 项目。 这些模型可以通过此本地 pipeline 封装类从 LangChain 调用。 要使用,您应该已安装 transformers Python ,以及 pytorchintel-extension-for-transformers
pip install transformers --quiet
pip install intel-extension-for-transformers

模型加载

可以使用 from_model_id 方法通过指定模型参数来加载模型。模型参数包括 intel_extension_for_transformers 中的 WeightOnlyQuantConfig 类。
from intel_extension_for_transformers.transformers import WeightOnlyQuantConfig
from langchain_community.llms.weight_only_quantization import WeightOnlyQuantPipeline

conf = WeightOnlyQuantConfig(weight_dtype="nf4")
hf = WeightOnlyQuantPipeline.from_model_id(
    model_id="google/flan-t5-large",
    task="text2text-generation",
    quantization_config=conf,
    pipeline_kwargs={"max_new_tokens": 10},
)
也可以通过直接传入现有的 transformers pipeline 来加载:
from intel_extension_for_transformers.transformers import AutoModelForSeq2SeqLM
from transformers import AutoTokenizer, pipeline

model_id = "google/flan-t5-large"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForSeq2SeqLM.from_pretrained(model_id)
pipe = pipeline(
    "text2text-generation", model=model, tokenizer=tokenizer, max_new_tokens=10
)
hf = WeightOnlyQuantPipeline(pipeline=pipe)

创建链

将模型加载到内存后,您可以将其与提示组合以形成链。
from langchain_core.prompts import PromptTemplate

template = """Question: {question}

Answer: Let's think step by step."""
prompt = PromptTemplate.from_template(template)

chain = prompt | hf

question = "What is electroencephalography?"

print(chain.invoke({"question": question}))

CPU 推理

目前 intel-extension-for-transformers 只支持 CPU 设备推理,Intel GPU 支持即将推出。在 CPU 机器上运行时,您可以指定 device="cpu"device=-1 参数将模型放在 CPU 设备上。 默认为 -1 表示 CPU 推理。
conf = WeightOnlyQuantConfig(weight_dtype="nf4")
llm = WeightOnlyQuantPipeline.from_model_id(
    model_id="google/flan-t5-large",
    task="text2text-generation",
    quantization_config=conf,
    pipeline_kwargs={"max_new_tokens": 10},
)

template = """Question: {question}

Answer: Let's think step by step."""
prompt = PromptTemplate.from_template(template)

chain = prompt | llm

question = "What is electroencephalography?"

print(chain.invoke({"question": question}))

批量 CPU 推理

您也可以在批量模式下在 CPU 上运行推理。
conf = WeightOnlyQuantConfig(weight_dtype="nf4")
llm = WeightOnlyQuantPipeline.from_model_id(
    model_id="google/flan-t5-large",
    task="text2text-generation",
    quantization_config=conf,
    pipeline_kwargs={"max_new_tokens": 10},
)

chain = prompt | llm.bind(stop=["\n\n"])

questions = []
for i in range(4):
    questions.append({"question": f"What is the number {i} in french?"})

answers = chain.batch(questions)
for answer in answers:
    print(answer)

intel-extension-for-transformers 支持的数据类型

我们支持将权重量化为以下数据类型进行存储(WeightOnlyQuantConfig 中的 weight_dtype):
  • int8:使用 8 位数据类型。
  • int4_fullrange:与普通 int4 范围 [-7,7] 相比,使用 int4 范围的 -8 值。
  • int4_clip:裁剪并保留 int4 范围内的值,将其他值设为零。
  • nf4:使用归一化浮点 4 位数据类型。
  • fp4_e2m1:使用常规浮点 4 位数据类型。“e2” 表示 2 位用于指数,“m1” 表示 1 位用于尾数。
虽然这些技术以 4 位或 8 位存储权重,但计算仍在 float32、bfloat16 或 int8 中进行(WeightOnlyQuantConfig 中的 compute_dtype):
  • fp32:使用 float32 数据类型计算。
  • bf16:使用 bfloat16 数据类型计算。
  • int8:使用 8 位数据类型计算。

支持的算法矩阵

intel-extension-for-transformers 支持的量化算法(WeightOnlyQuantConfig 中的 algorithm):
算法PyTorchLLM Runtime
RTN
AWQ敬请期待
TEQ敬请期待
RTN: 一种直观的量化方法,不需要额外的数据集,是一种非常快速的量化方法。一般来说,RTN 会将权重转换为均匀分布的整数数据类型,但一些算法(如 Qlora)提出了非均匀的 NF4 数据类型并证明了其理论最优性。
AWQ: 证明了只保护 1% 的显著权重可以大大减少量化误差。显著权重通道通过观察每个通道的激活和权重分布来选择。显著权重在量化前乘以一个大的缩放因子以保持精度后也进行量化。
TEQ: 一种可训练的等价变换,在仅权重量化中保持 FP32 精度。它受 AWQ 启发,同时提供了一种新的方法来搜索激活和权重之间的最优每通道缩放因子。