0


使用Torch Compile提高大语言模型的推理速度

Torch Compile(torch.compile)虽然最初随PyTorch 2.0一同推出,但经过多次更新和优化后,才得以可靠地支持大多数大型语言模型(LLMs)。

在推理方面,torch.compile能够真正加快解码速度,同时仅略微增加内存使用量。

在本文中,我们将探讨torch.compile的工作原理,并测量其对LLMs推理性能的影响。要在代码中使用torch.compile,只需添加一行代码即可。在本文中,我使用Llama 3.2进行了测试,并尝试了与bitsandbytes量化结合使用,分别在两种不同的GPU上进行了测试:Google Colab的L4和A100。

Torch Compile:如何让模型更快?

torch.compile提供了一种通过将标准PyTorch代码转换为优化后的机器代码来加速模型的方法。这种称为即时编译(JIT,Just-In-Time)的方法,使代码在特定硬件上运行更加高效,即比普通Python代码更快。对于复杂模型而言,即使是很小的速度提升也能累积成显著的时间节省。

torch.compile背后的核心工具包括PyTorch编译器中的几个重要组件:

  • TorchDynamo:该工具在执行期间修改Python代码,以允许PyTorch将操作捕获为图,然后由torch.compile进行优化。
  • AOTAutograd:该工具根据捕获的图生成训练所需的梯度。
  • PrimTorch:它将复杂操作简化为更小、更易于管理的组件。
  • TorchInductor:该组件接受优化后的图,并为GPU、CPU和其他硬件设置生成硬件优化代码。
  • torch.compile的一个主要优势是易于使用。它只需将模型用torch.compile包裹起来,即可生成优化版本。它与现有的PyTorch代码无缝集成。

首次运行带有torch.compile的模型时,它会执行初始优化,后续调用将受益于这个更快的版本。torch.compile遵循一个三步过程:

  • 它将模型分解为更小、优化的段,保留任何不可优化的代码。
  • 调整PyTorch操作以适应特定的硬件后端。
  • 编译这些部分,以在你的设备上实现最大效率,主要通过减少内存传输来实现。

其他优化包括将多个操作合并为单个内核调用,并使用CUDA图捕获来提升GPU性能。虽然并非模型的每个部分都能被优化,但torch.compile通常能加速大多数模型,而无需进行结构更改。

但是也存在一些限制。具有不同输入形状的模型可能会触发重复编译,从而减慢速度。一致的输入形状有助于避免此问题,尽管对于LLMs的推理和微调而言,这通常不是问题。

编译后的模型也可能消耗更多内存或运行速度低于预期,因此建议进行基准测试以确认torch.compile是否提高了特定设置下的性能。在分布式设置中,优化可能并不总是均匀应用,因此最好在配置分布式进程之前编译模型。

Torch Compile与Transformers

为了充分利用torch.compile的加速效果,我们可以通过将模型传递给它来轻松启用torch.compile,如下所示:

 importtorch
 model=torch.compile(model)

Hugging Face发布了一些关于torch.compile对视觉模型影响的有趣基准测试结果。

让我们看看它在LLMs上的表现如何。

Torch Compile在LLMs上的应用

我尝试使用torch.compile与Llama 3.2 3B模型结合。

 importtorch
 fromtransformersimportAutoTokenizer, AutoModelForCausalLM
 checkpoint="meta-llama/Llama-3.2-3B"
 tokenizer=AutoTokenizer.from_pretrained(checkpoint) 
 model=AutoModelForCausalLM.from_pretrained(checkpoint, device_map="cuda") 
 model=torch.compile(model)

为了对使用torch.compile的推理进行基准测试,我使用了optimum benchmark(Apache 2.0许可),批处理大小为1,序列长度为1024。我们将特别关注预填充(KV缓存创建、编码)和解码(标记生成)阶段的吞吐量(标记/秒),以及模型编译后的内存消耗。

torch.compile在首次使用时需要一些时间来编译模型。为了获得准确的基准测试结果,最好先运行几次预热迭代。这样,推理速度和内存使用等性能指标仅在模型完全编译后进行测量。

我还测试了torch.compile对使用bitsandbytes(BnB)量化到4位的Llama 3.2(3B)模型的影响。

在A100 GPU(Google Colab)上的结果:

torch.compile显著提高了解码速度,吞吐量几乎翻倍(如中间图表所示)。它还改善了预填充阶段的性能,尽管程度较小。然而,当在A100 GPU上将torch.compile与bitsandbytes量化模型结合使用时,对性能的影响很小,甚至可能略微减慢预填充阶段的速度。

在内存使用方面,如预期那样,编译后的模型消耗了更多内存。增加的内存约为+200 MB(约占模型大小的3%),相对较小且易于管理。

在L4 GPU(Google Colab)上的结果:

在L4 GPU上,其内存是A100的一半,我们观察到了类似的内存消耗增加,但加速效果很小。这与A100上的结果形成鲜明对比,表明torch.compile的有效性可能因使用的GPU而异。

简而言之,值得在你的特定GPU上对torch.compile进行基准测试,以查看它是否提供了预期的性能提升。

总结

torch.compile可以在标准设置中显著加快推理速度,特别是在不涉及量化的情况下。但是建议在模型开发过程的最后阶段才启用torch.compile,即在你已经配置好所有计划用于生产的特性和技术之后。这种方法至关重要,因为根据你的模型和GPU,torch.compile可能与某些配置的行为不符合预期。

例如可能会遇到FlashAttention和bfloat16的兼容性问题,它们并不总是能与torch.compile顺利配合使用。

如果你正在使用LoRA适配器,请注意加速收益可能较低。LoRA组件具有高度动态性,这使得它们难以有效编译。

但是torch.compile可以是一个强大的加速工具,铜鼓哦仔细测试可以确保它与你的特定设置和要求相符。

作者:Benjamin Marie

“使用Torch Compile提高大语言模型的推理速度”的评论:

还没有评论