通过 CPU 优化推理¶
通过一些优化技术,可以在 CPU 上高效地运行大型模型的推理。其中一种优化方法是将 PyTorch 代码编译成中间格式,以便在高性能环境中(如 C++)运行。另一种方法是将多个操作合并到一个内核中,以减少每个操作单独运行时的开销。
在这篇文章中,你会学到如何使用 BetterTransformer 提高推理速度,以及如何将 PyTorch 代码转换为 TorchScript。如果你使用的是英特尔 CPU,还可以利用 英特尔扩展库 中的图优化技术进一步提高推理速度。最后,你将学到如何使用 🤗 Optimum 通过 ONNX Runtime 或 OpenVINO(如果你使用的是英特尔 CPU)加速推理。
BetterTransformer¶
BetterTransformer 通过其快速路径(原生 PyTorch 专门实现的 Transformer 函数)执行来加速推理。快速路径执行中的两种优化技术是:
- 融合:将多个连续的操作合并到一个“内核”中,以减少计算步骤的数量。
- 跳过填充标记的固有稀疏性:避免对嵌套张量进行不必要的计算。
BetterTransformer 还将所有注意力操作转换为使用更节省内存的 缩放点积注意力。
并不是所有模型都支持 BetterTransformer。请查看这个 列表,看看你的模型是否支持 BetterTransformer。
在开始之前,请确保已经安装了 🤗 Optimum。你可以参考 安装指南 安装。
使用 PreTrainedModel.to_bettertransformer() 方法启用 BetterTransformer:
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("bigcode/starcoder", torch_dtype="auto")
TorchScript¶
TorchScript 是一种 PyTorch 模型表示形式,可以在生产环境中用于性能至关重要的场景。你可以先在 PyTorch 中训练模型,然后将其导出为 TorchScript,以摆脱 Python 性能限制。PyTorch 通过 追踪 模型返回一个优化过的 ScriptFunction,该函数通过即时编译(JIT)进行优化。与默认的急切模式相比,PyTorch 的 JIT 模式通常通过操作融合等优化技术在推理时提供更好的性能。
要了解 TorchScript 的基本概念,可以参考 PyTorch TorchScript 入门教程。
使用 Trainer 类时,可以通过设置 --jit_mode_eval 标志来启用 CPU 推理的 JIT 模式:
python examples/pytorch/question-answering/run_qa.py \
--model_name_or_path csarron/bert-base-uncased-squad-v1 \
--dataset_name squad \
--do_eval \
--max_seq_length 384 \
--doc_stride 128 \
--output_dir /tmp/ \
--no_cuda \
--jit_mode_eval
对于 PyTorch >= 1.14.0,JIT 模式可以通过支持字典输入的 jit.trace 来受益于任何模型的预测和评估。
对于 PyTorch < 1.14.0,如果模型的前向参数顺序与 jit.trace 中的元组输入顺序匹配(例如问答模型),JIT 模式可以受益。如果前向参数顺序不匹配(例如文本分类模型),jit.trace 将失败,并通过异常捕获回退。日志用于通知用户。
IPEX 图优化¶
英特尔® 扩展库(IPEX)在 JIT 模式下为英特尔 CPU 提供了进一步的优化,我们建议将其与 TorchScript 结合使用以获得更快的性能。IPEX 图优化 可以融合多头注意力、拼接线性层、线性+加法、线性+Gelu、加法+层归一化等多种操作。
要利用这些图优化,请确保已安装 IPEX。你可以参考 安装指南 安装:
pip install intel_extension_for_pytorch
在 Trainer 类中设置 --use_ipex 和 --jit_mode_eval 标志以启用带有图优化的 JIT 模式:
python examples/pytorch/question-answering/run_qa.py \
--model_name_or_path csarron/bert-base-uncased-squad-v1 \
--dataset_name squad \
--do_eval \
--max_seq_length 384 \
--doc_stride 128 \
--output_dir /tmp/ \
--no_cuda \
--use_ipex \
--jit_mode_eval
🤗 Optimum¶
有关如何使用 ORT 与 🤗 Optimum 的详细信息,请参阅 使用 ONNX Runtime 进行 Optimum 推理 指南。本节仅提供一个简短而简单的示例。
ONNX Runtime(ORT)是一种模型加速器,默认情况下在 CPU 上运行推理。ORT 由 🤗 Optimum 支持,可以在 🤗 Transformers 中使用,而无需对代码进行太多更改。你只需要将 🤗 Transformers 的 AutoClass 替换为其等效的 ORTModel,并加载一个 ONNX 格式的检查点。
例如,如果你正在运行一个问答任务的推理,可以加载 optimum/roberta-base-squad2 检查点,其中包含一个 model.onnx 文件:
from transformers import AutoTokenizer, pipeline
from optimum.onnxruntime import ORTModelForQuestionAnswering
model = ORTModelForQuestionAnswering.from_pretrained("optimum/roberta-base-squad2")
tokenizer = AutoTokenizer.from_pretrained("deepset/roberta-base-squad2")
onnx_qa = pipeline("question-answering", model=model, tokenizer=tokenizer)
question = "我的名字是什么?"
context = "我的名字是 Philipp,我住在纽伦堡。"
pred = onnx_qa(question, context)
如果你使用的是英特尔 CPU,请查看 🤗 Optimum Intel,它支持多种压缩技术(量化、剪枝、知识蒸馏)和工具,用于将模型转换为 OpenVINO 格式,以实现更高性能的推理。