让你的人驼世代飞跃,使用AWS Inferentia2

使用AWS Inferentia2,让你的人驼世代飞跃

Hugging Face博客的先前文章中,我们介绍了第二代AWS Inferentia加速器——AWS Inferentia2,并解释了你可以如何使用optimum-neuron在AWS Inferentia 2实例上快速部署Hugging Face模型,用于标准文本和视觉任务。

在与AWS Neuron SDK进一步集成的过程中,现在可以使用🤗optimum-neuron来在AWS Inferentia2上部署用于文本生成的LLM模型。

对于这个演示,我们选择的模型是Llama 2,它是在Hugging Face hub上最受欢迎的模型之一。

在Inferentia2实例上设置🤗 optimum-neuron

我们建议使用Hugging Face Neuron深度学习AMI (DLAMI)。DLAMI已为您预装了所有所需的库,包括Optimum Neuron、Neuron Drivers、Transformers、Datasets和Accelerate。

另外,您也可以使用Hugging Face Neuron SDK DLC在Amazon SageMaker上进行部署。

注意:请关注即将发布的致力于SageMaker部署的文章。

最后,这些组件也可以按照optimum-neuron 安装说明手动安装到新的Inferentia2实例上。

将Llama 2模型导出到Neuron

正如optimum-neuron文档中所解释的那样,模型在在Neuron设备上运行之前需要被编译和导出为序列化格式。

幸运的是,🤗optimum-neuron提供了一个非常简单的API,可以将标准🤗transformers模型导出为Neuron格式。

>>> from optimum.neuron import NeuronModelForCausalLM>>> compiler_args = {"num_cores": 24, "auto_cast_type": 'fp16'}>>> input_shapes = {"batch_size": 1, "sequence_length": 2048}>>> model = NeuronModelForCausalLM.from_pretrained(        "meta-llama/Llama-2-7b-hf",        export=True,        **compiler_args,        **input_shapes)

这需要一点解释:

  • 使用compiler_args,我们指定要将模型部署到多少个核心上(每个neuron设备有两个核心),以及使用哪种精度(此处为float16),
  • 使用input_shape,我们设置模型的静态输入和输出维度。所有模型编译器都需要静态形状,neuron也不例外。请注意sequence_length不仅约束了输入上下文的长度,还约束了KV缓存的长度,因此也约束了输出长度。

根据您选择的参数和inferentia主机,这可能需要几分钟到一小时以上的时间。

幸运的是,您只需执行一次此操作,因为您可以保存模型并以后重新加载它。

>>> model.save_pretrained("一个本地路径,用于编译神经元模型")

更好的是,您可以将其推送到Hugging Face Hub

>>> model.push_to_hub("一个本地路径,用于编译神经元模型", repository_id="aws-neuron/Llama-2-7b-hf-neuron-latency")

使用AWS Inferentia2上的Llama 2生成文本

一旦导出模型,您可以使用transformers库生成文本,具体描述请参见此前的帖子中的详细信息

>>> from optimum.neuron import NeuronModelForCausalLM>>> from transformers import AutoTokenizer>>> model = NeuronModelForCausalLM.from_pretrained('aws-neuron/Llama-2-7b-hf-neuron-latency')>>> tokenizer = AutoTokenizer.from_pretrained("aws-neuron/Llama-2-7b-hf-neuron-latency")>>> inputs = tokenizer("什么是深度学习?", return_tensors="pt")>>> outputs = model.generate(**inputs,                             max_new_tokens=128,                             do_sample=True,                             temperature=0.9,                             top_k=50,                             top_p=0.9)>>> tokenizer.batch_decode(outputs, skip_special_tokens=True)['什么是深度学习?\n“深度学习”一词指的是一种旨在以多个逐渐复杂的处理节点的层次结构形式对数据进行高层抽象的机器学习类型。']

注意:当将多个输入提示传递给模型时,生成的标记序列必须以流结束标记向左填充。导出的模型附带的标记器已进行相应配置。

支持以下生成策略:

  • 贪婪搜索
  • 使用top-k和top-p的多项式抽样(带有温度)

大多数logits的预处理/过滤(如重复惩罚)都得到支持。

优化神经元管道的一体化

对于那些喜欢简单的人,使用LLM在AWS Inferentia 2上的模型有更简单的方法,只需使用优化神经元管道

使用它们就像这样简单:

>>> from optimum.neuron import pipeline>>> p = pipeline('text-generation', 'aws-neuron/Llama-2-7b-hf-neuron-budget')>>> p("我的地球上最喜欢的地方是", max_new_tokens=64, do_sample=True, top_k=50)[{'generated_text': '我的地球上最喜欢的地方是大海。那是我感到最平静的地方。我喜欢旅行和看到新的地方。我有一个'}]

基准测试

但在Inferentia2上的文本生成效率有多高呢?让我们找出答案!

我们在hub上上传了LLama 2 7B和13B模型的经过预编译的版本,具有不同的配置:

注意:所有模型都编译为具有最大序列长度2048。

llama2 7B “budget”模型专为只有一个神经元设备和足够cpu内存以加载模型的inf2.xlarge实例部署。

所有其他模型都编译为利用inf2.48xlarge实例上可用的所有核心。

注意:有关可用实例的详细信息,请参考inferentia2产品页面

我们为llama2 7Bllama2 13B模型创建了两个“延迟”导向的配置,每次只能处理一个请求,但速度全开。

我们还创建了两个“吞吐量”导向的配置,可以同时处理四个请求。

为了评估模型,我们从256个输入令牌开始,生成总序列长度为1024个令牌(即我们生成了256、512和768个令牌)。

注意:在图表中报告了“budget”模型数值,但未包含在其中以提高可读性。

编码时间

编码时间是处理输入令牌并生成第一个输出令牌所需的时间。它是一个非常重要的指标,因为它对应于用户在流式生成令牌时直接感知的延迟。

我们测试了不断增加的上下文大小的编码时间,其中256个输入令牌大致对应于典型的问答使用情况,而768个令牌则更符合检索增强生成(RAG)用例的典型情况。

“budget”模型(Llama2 7B-B)部署在inf2.xlarge实例上,而其他模型部署在inf2.48xlarge实例上。

编码时间以为单位。

Llama2 inferentia2 encoding-time

我们可以看到,所有部署的模型在处理长上下文时都展现出了出色的响应时间。

端到端延迟

端到端延迟对应于达到1024个令牌的总时间。

因此,它包括编码和生成时间。

“budget”模型(Llama2 7B-B)部署在inf2.xlarge实例上,而其他模型部署在inf2.48xlarge实例上。

延迟以为单位。

Llama2 inferentia2 end-to-end latency

所有部署在高端实例上的模型都具有良好的延迟,即使那些实际上被配置为优化吞吐量的模型也是如此。

“budget”部署模型的延迟要高得多,但仍然可以接受。

吞吐量

我们采用与其他基准测试相同的约定来评估吞吐量,即通过将端到端延迟除以输入和输出令牌的总和来计算。换句话说,我们将端到端延迟除以batch_size * sequence_length,以获得每秒生成的令牌数。

“budget”模型(Llama2 7B-B)部署在inf2.xlarge实例上,而其他模型部署在inf2.48xlarge实例上。

吞吐量以每秒令牌数为单位。

Llama2 inferentia2 throughput

同之前一样,部署在高端实例上的模型具有非常出色的吞吐量,即使那些经过优化以提高延迟的模型也如此。

“budget”模型的吞吐量要低得多,但对于流式使用情况来说仍然可以接受,考虑到平均阅读者每秒读大约5个单词。

结论

我们展示了使用🤗optimum-neuron,从Hugging Face中心AWS Inferentia2上部署llama2模型的简单方法。

部署的模型在编码时间、延迟和吞吐量方面表现非常好。

有趣的是,部署的模型的延迟对批处理大小并不太敏感,这为其在推断端点上为多个请求同时提供服务打开了道路。

虽然还有很大的改进空间:

  • 在当前实现中,增加批处理大小是提高吞吐量的唯一方法,但目前受到设备内存的限制。目前还在集成其他选项,如流水线处理。
  • 静态序列长度限制了模型对长上下文进行编码的能力。有趣的是,看看注意力下沉是否可以作为解决这个问题的有效选项。