英特尔仅权重量化
使用英特尔转换器管道扩展对 Huggingface 模型进行仅权重量化
Hugging Face 模型可以通过 WeightOnlyQuantPipeline
类在本地运行,并进行仅权重量化。
Hugging Face 模型中心 托管了超过 12 万个模型、2 万个数据集和 5 万个演示应用程序(Spaces),所有这些都是开源的,并且在在线平台上公开可用,人们可以在此平台上轻松协作并一起构建机器学习。
可以通过此本地管道包装器类从 LangChain 调用这些模型。
要使用,您应该安装 transformers
python 包,以及 pytorch、intel-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
管道来加载模型。
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 设备推理。将很快支持英特尔 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)
英特尔转换器扩展支持的数据类型
我们支持将权重量化为以下数据类型以进行存储(WeightOnlyQuantConfig 中的 weight_dtype)
- int8: 使用 8 位数据类型。
- int4_fullrange: 与普通 int4 范围相比,使用 int4 范围的 -8 值。[-7,7].
- 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 位数据类型进行计算。
支持的算法矩阵
英特尔转换器扩展中支持的量化算法(WeightOnlyQuantConfig 中的 algorithm)
算法 | PyTorch | LLM 运行时 |
---|---|---|
RTN | ✔ | ✔ |
AWQ | ✔ | 敬请期待 |
TEQ | ✔ | 敬请期待 |
RTN: 一种我们可以直观理解的量化方法。它不需要额外的 dataset,是一种非常快的量化方法。一般来说,RTN 会将权重转换为均匀分布的整数数据类型,但一些算法,例如 Qlora,提出了非均匀 NF4 数据类型并证明了其理论最优性。
AWQ: 证明了仅保护 1% 的显著权重就可以大大减少量化误差。通过观察每个通道的激活和权重的分布来选择显著权重通道。显著权重在量化之前也会乘以一个大的缩放因子以进行量化,以便进行保留。
TEQ: 一种可训练的等效转换,可在仅权重量化中保留 FP32 精度。它受到 AWQ 的启发,同时提供了一种新的解决方案来搜索激活和权重之间最佳的每个通道缩放因子。