共计 5075 个字符,预计需要花费 13 分钟才能阅读完成。
在 最近的一篇文章 中,咱们介绍了代号为 Sapphire Rapids 的第四代英特尔至强 CPU 及其新的先进矩阵扩大 (AMX) 指令集。通过应用 Amazon EC2 上的 Sapphire Rapids 服务器集群并联合相应的英特尔优化库,如 英特尔 PyTorch 扩大 (IPEX),咱们展现了如何应用 CPU 进行高效的分布式大规模训练,与上一代至强 (Ice Lake) 相比,Sapphire Rapids 实现了 8 倍的减速,获得了近线性的扩大比。
本文咱们将重点关注推理。应用基于 PyTorch 的 Hugging Face transformers 模型,咱们首先在 Ice Lake 服务器上别离测量它们在长、短两种文本序列上的性能。而后,咱们在 Sapphire Rapids 服务器和最新版本的 Hugging Face Optimum Intel 上执行雷同的测试,并比拟两代 CPU 的性能。这里,Optimum Intel 是一个专用于英特尔平台的硬件加速开源库。
让咱们开始吧!
为什么你应该思考应用 CPU 推理
在决定应用 CPU 还是 GPU 进行深度学习推理时须要思考多个因素。最重要的当然是模型的大小。一般来说,较大的模型能更多地受害于 GPU 提供的弱小算力,而较小的模型能够在 CPU 上高效运行。
另一个须要思考的因素是模型和推理工作自身的并行度。GPU 为大规模并行处理而设计,因而它们可能对那些能够高度并行化的工作更高效。而另一方面,如果模型或推理工作并没有特地高的并行度,CPU 可能是更无效的抉择。
老本也是一个须要思考的重要因素。GPU 可能很低廉,而应用 CPU 可能是一种性价比更高的抉择,尤其是在业务利用并不需要极低提早的状况下。此外,如果你须要可能轻松扩缩推理实例的数量,或者如果你须要可能在各种平台上进行推理,应用 CPU 可能是更灵便的抉择。
当初,让咱们开始配置咱们的测试服务器。
配置咱们的测试服务器
和上一篇文章一样,咱们将应用 Amazon EC2 实例:
- 一个基于 Ice Lake 架构
c6i.16xlarge
实例, - 一个基于 Sapphire Rapids 架构的
r7iz.16xlarge-metal
实例。你能够在 AWS 网站上获取无关新 r7iz 系列的更多信息。
两个实例都有 32 个物理核 (因而有 64 个 vCPU)。咱们将用雷同的形式来设置它们:
- Ubuntu 22.04 和 Linux 5.15.0 (
ami-0574da719dca65348
), - PyTorch 1.13 与 IPEX (Intel Extension for PyTorch) 1.13,
- Transformers 4.25.1。
惟一的区别是在 r7iz 实例上咱们多装一个 Optimum Intel 库。
以下是设置步骤。像平常一样,咱们倡议应用虚拟环境来保障环境污浊。
sudo apt-get update
# 装置 libtcmalloc,获取更好性能
sudo apt install libgoogle-perftools-dev -y
export LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libtcmalloc.so"
sudo apt-get install python3-pip -y
pip install pip --upgrade
export PATH=/home/ubuntu/.local/bin:$PATH
pip install virtualenv
virtualenv inference_env
source inference_env/bin/activate
pip3 install torch==1.13.0 -f https://download.pytorch.org/whl/cpu
pip3 install intel_extension_for_pytorch==1.13.0 -f https://developer.intel.com/ipex-whl-stable-cpu
pip3 install transformers
# 仅需在 r7iz 实例上装置
pip3 install optimum [intel]
在两个实例上实现上述步骤后,咱们就能够开始运行测试了。
对风行的 NLP 模型进行基准测试
在这个例子中,咱们将在文本分类工作上对几个 NLP 模型进行基准测试: distilbert-base-uncased, bert-base-uncased 和 roberta-base。你能够在 Github 上找到 残缺脚本。当然,你也能够用你本人的模型随便尝试!
models = ["distilbert-base-uncased", "bert-base-uncased", "roberta-base"]
咱们应用序列长度别离为 16 和 128 的两种句子来测试,同时咱们也将在这两种句子上别离测量单句推理和批量推理的均匀预测提早和 p99 预测提早。该测试计划模仿了实在场景,因而能够较好地近似在实在场景中的预期减速比。
sentence_short = "This is a really nice pair of shoes, I am completely satisfied with my purchase"
sentence_short_array = [sentence_short] * 8
sentence_long = "These Adidas Lite Racer shoes hit a nice sweet spot for comfort shoes. Despite being a little snug in the toe box, these are very comfortable to wear and provide nice support while wearing. I would stop short of saying they are good running shoes or cross-trainers because they simply lack the ankle and arch support most would desire in those type of shoes and the treads wear fairly quickly, but they are definitely comfortable. I actually walked around Disney World all day in these without issue if that is any reference. Bottom line, I use these as the shoes they are best; versatile, inexpensive, and comfortable, without expecting the performance of a high-end athletic sneaker or expecting the comfort of my favorite pair of slippers."
sentence_long_array = [sentence_long] * 8
基准测试性能非常简单。在几次预热迭代后,咱们应用 pipeline
API 运行 1000 次预测,把预测工夫存下来,并计算它们的均值和 p99 值。
import time
import numpy as np
def benchmark (pipeline, data, iterations=1000):
# 预热 100 次
for i in range (100):
result = pipeline (data)
times = []
for i in range (iterations):
tick = time.time ()
result = pipeline (data)
tock = time.time ()
times.append (tock - tick)
return "{:.2f}".format (np.mean (times) * 1000), "{:.2f}".format (np.percentile (times, 99) * 1000
)
在 c6i (Ice Lake) 实例上,咱们只应用一般的 Transformers pipeline
。
from transformers import pipeline
for model in models:
print (f"Benchmarking {model}")
pipe = pipeline ("sentiment-analysis", model=model)
result = benchmark (pipe, sentence_short)
print (f"Transformers pipeline, short sentence: {result}")
result = benchmark (pipe, sentence_long)
print (f"Transformers pipeline, long sentence: {result}")
result = benchmark (pipe, sentence_short_array)
print (f"Transformers pipeline, short sentence array: {result}")
result = benchmark (pipe, sentence_long_array)
print (f"Transformers pipeline, long sentence array: {result}")
在 r7iz (Sapphire Rapids) 实例上,咱们同时应用一般 pipeline
和 Optimum pipeline
。在 Optimum pipeline
中,咱们启用 bfloat16
模式以利用到 AMX 指令,并将 jit
设置为 True
以应用即时编译进一步优化模型。
import torch
from optimum.intel import inference_mode
with inference_mode (pipe, dtype=torch.bfloat16, jit=True) as opt_pipe:
result = benchmark (opt_pipe, sentence_short)
print (f"Optimum pipeline, short sentence: {result}")
result = benchmark (opt_pipe, sentence_long)
print (f"Optimum pipeline, long sentence: {result}")
result = benchmark (opt_pipe, sentence_short_array)
print (f"Optimum pipeline, short sentence array: {result}")
result = benchmark (opt_pipe, sentence_long_array)
print (f"Optimum pipeline, long sentence array: {result}")
为简洁起见,咱们先看下 distilbert-base-uncased 的 p99 后果。你能够在文章开端找到所有测例的残缺后果。
如上图所示,与上一代至强 CPU 相比,Sapphire Rapids 上单个句子的预测提早减速了 60-65%。也就是说,因为联合了英特尔 Sapphire Rapids 平台以及 Hugging Face Optimum 的优化,你只需对代码进行很少改变就可将预测速度进步 3 倍。
这让咱们即便在长文本序列上也能够达到 个位数的预测提早 。在 Sapphire Rapids 之前,这样的性能只有通过 GPU 能力实现。
论断
第四代英特尔至强 CPU 提供了杰出的推理性能,尤其是在与 Hugging Face Optimum 联合应用时。这是深度学习在更易得和更具老本效益的路线上的又一个提高,咱们期待与英特尔的敌人们在这条路线上持续单干。
以下是一些可帮忙你入门的其余资源:
- 英特尔 IPEX GitHub
- Hugging Face Optimum GitHub
如果你有任何问题或反馈,咱们很乐意在 Hugging Face 论坛 上与你交换。
感激浏览!
附录: 残缺后果
基准测试软件环境:
- Ubuntu 22.04 with libtcmalloc
- Linux 5.15.0 patched for Intel AMX support
- PyTorch 1.13 with Intel Extension for PyTorch
- Transformers 4.25.1
- Optimum 1.6.1
- Optimum Intel 1.7.0.dev0
英文原文: https://hf.co/blog/intel-sapphire-rapids-inference
译者: Matrix Yao (姚伟峰),英特尔深度学习工程师,工作方向为 transformer-family 模型在各模态数据上的利用及大规模模型的训练推理。
审校、排版: zhongdongy (阿东)