全面解析 LLM 推理性能的关键因素

本文详细分析了大型语言模型(LLM)推理性能的关键因素,包括LLM推理过程、KV Cache、访存瓶颈、评估指标以及各种影响因素,如硬件环境、分布式策略、精度类型、模型类型和数据分布等。通过实例和实验数据,揭示了硬件选择、分布式策略和优化方法如何显著影响LLM的推理效率和性能。文章指出,尽管LLM推理面临诸多挑战,如复杂性和访存限制,但通过综合考虑不同因素,可以实现性能优化和成本效益的最大化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、背景介绍

自 OpenAI 一年前发布 ChatGPT 以来,大型语言模型(LLM)领域经历了前所未有的快速发展。在短短一年时间内,涌现出了数以百计的 LLM 模型,包括开源模型如 LLaMA、Mistral、Yi、Baichuan、Qwen,以及闭源模型如 Claude、Gemini 等。这些模型的出现不仅丰富了人工智能的应用领域,也对模型推理框架提出了新的挑战。

与传统的 AI 模型不同,LLM 的推理过程具有其独特性,简单套用传统 AI 模型的推理框架往往难以满足效率和性能的需求。因此,针对 LLM 的特点,业内出现了一系列专门的推理框架,如vLLM、Huggingface TGI、DeepSpeed-MII、NVIDIA 的  TensorRT-LLM,以及国内的 LMdeploy 等,这些框架旨在优化和加速 LLM 推理,简化部署流程。

然而,在目前的工业界和学术界,尚未形成一个统一且完善的 LLM 推理性能基准测试(Benchmark)工具。这意味着在进行 LLM 的私有化推理部署时,往往缺乏有效的参考基准,需要进行重复的性能评估,以在不同的条件和方案中做出最优选择。造成这一状况的主要原因是影响LLM 推理性能的因素众多且复杂,包括但不限于硬件类型、模型配置、数据分布以及采用的优化策略等。

本文旨在全面总结这些因素,通过对各种影响因素的分析和探讨,提供一个全景式的视角来指导LLM 的推理部署。我们的目标是帮助读者在面对多样化的部署选项时,能够以最小的代价做出充分且明智的评估,从而优化 LLM 应用。

二、LLM 推理介绍

2.1 LLM 推理过程

当前的主流 LLM 基本都是 Decoder Only 的 Transformer 模型,其推理过程可以分为两个阶段:

  • Prefill:根据输入 Tokens(Recite, the, first, law, of, robotics) 生成第一个输出 Token(A),通过一次 Forward 就可以完成,在 Forward 中,输入 Tokens 间可以并行执行(类似 Bert 这些 Encoder 模型),因此执行效率很高。

  • Decoding:从生成第一个 Token(A) 之后开始,采用自回归方式一次生成一个 Token,直到生成一个特殊的 Stop Token(或者满足用户的某个条件,比如超过特定长度) 才会结束,假设输出总共有 N 个 Token,则 Decoding 阶段需要执行 N-1 次 Forward,这 N-1 次 Forward 只能串行执行,效率很低。另外,在生成过程中,需要关注的 Token 越来越多(每个 Token 的生成都需要 Attention 之前的 Token),计算量也会适当增大。

2.2 KV Cache

如下图所示,在 LLM 推理中最关键的就是下图中的 Multi-Head Attention,其主要的计算集中在左图中灰色的 Linear(矩阵乘)和 Scaled Dot-Product Attention 中的 MatMul 矩阵乘法:

图片

图片

如上右图中的 Mask 是一个下三角矩阵,也是因为这个下三角矩阵实现了 LLM Decoder 的主要特性,每个 Token 都只能看到当前位置及之前的 Token。

如下图所示,其中的 QKT 可以理解为一个相关性矩阵,如动图所示,4 个 Token 对应 4 个 Step,其中:

  • Step 2 依赖 Step 1 的结果,相关性矩阵的第 1 行不用重复计算

  • Step 3 依赖 Step 1 和 Step 2 的结果,相关性矩阵的第 1 行和第 2 行不用重复计算

  • Step 4 依赖 Step 1、Step 2 和 Step 3 的结果,相关性矩阵的第 1 行、第 2 行和第 3 行不用重复计算

在 Decoding 阶段 Token 是逐个生成的,上述的计算过程中每次都会依赖之前的结果,此时最简单的思路就是 Cache 之前计算过的中间结果,在计算当前 Token 时直接从 Cache 中读取而不是重新计算,如下图所示,上面是没有 Cache 的情况,下面是有 Cache 的情况:

图片

如下表所示,在 T4 GPU 上以 GPT2 模型为例验证有无 Cache 对推理时延的影响,其加速效果非常明显,因此也成为 LLM 推理的标配:

GPT2/T4

无 KV Cache

有 KV Cache

加速比

Output Token 1000

52.53s

9.12s

5.76x

当然,KV Cache 也有一定不足,其相当于使用空间换时间,占用的显存会大幅增加,尤其是对于参数规模较大的模型。比如,对于 Vicuna-13B 模型(FP16 推理,其 Transformer layer num=40, embedding size=5120)来说,在 Sequence Length=1024,batch size=8 下,KV 缓存所占显存大小为 2 * 2 * 40 * 5120 * 1024 * 8 = 6.7G。

2.3 访存瓶颈

因为 Decoding 阶段 Token 逐个处理,使用 KV Cache 之后,上面介绍的 Multi-Head Attention 里的矩阵乘矩阵操作全部降级为矩阵乘向量。

除此之外,Transformer 模型中的另一个关键组件 FFN 中主要也包含两个矩阵乘法操作,但是 Token 之间不会交叉融合,也就是任何一个 Token 都可以独立计算,因此在 Decoding 阶段不用 Cache 之前的结果,但同样会出现矩阵乘矩阵操作降级为矩阵乘向量。

图片

矩阵乘向量操作是明显的访存 bound,而以上操作是 LLM 推理中最主要的部分,这也就导致 LLM 推理是访存 bound 类型。

基于 V100 GPU,FP16 精度,LLM 推理 Prefill 阶段和 Decoding 阶段的 Roofline Model 可以近似表示如下(理论上限),其中

  • 三角表示 Prefill 阶段:假设 Batch size 为 1,Sequence Length 越大,计算强度越大,通常都会位于 Compute Bound 区域。

  • 圆表示 Decoding 阶段:Batch size 越大,计算强度越大,理论性能峰值越大,通常都会位于 Memory Bound 区域。

图片

如下图所示,Prefill 阶段在比较小 Batch Size 下就可以获得比较大的计算强度,相应的吞吐也很高;而 Decoding 阶段需要比较大的 Batch Size 才能获得相对高的计算强度及吞吐(图片来自 [2308.16369] SARATHI: Efficient LLM Inference by Piggybacking Decodes with Chunked Prefills ):

图片

2.4 LLM 评估指标

针对 LLM 推理服务通常有两种调用模式,一种是传统的请求方式,一次请求获得所有的生成 Token,这种方式的好处是请求链路比较简单,但 LLM 推理的时间往往比较长,可能需要数秒,这也导致用户体验很不好;另一种是像 ChatGPT 一样的 Streaming 方式,其不是一次返回所有 Token,而是一边生成一边返回,只要生成速度大于人的阅读速度就能获得很好的用户体验。

针对上述的两种方式,也就引申出不同的评估指标。对于非 Streaming 模式,通常需要评估其整个请求的延迟(Latency),请求粒度的 QPS(Throughput);针对 Streaming 模式,通常需要评估第一个 Token 生成的时延(Time To First Token,TTFT)和后续每个 Token 的时延(Time Per Output Token,TPOT,也就对应每秒能生成的 Token 数目)。除此之外,在评估时延时通常也需要按照不同的维度评估,比如平均时延、P90 时延、P99 时延等。

除了以上的服务指标外,服务的成本也是需要考虑的重要因素,比如 V100、A100 和 H100 哪种硬件更适合 LLaMA 13B 模型的推理部署,成本更低?

2.5 影响 LLM 输出结果的因素

在进行 LLM 推理优化、性能评估时首先要保证生成结果的对齐,然而这并不总能保证,主要有以下几个影响因素:

  • 低精度量化(KV Cache INT8、GPTQ INT4、AWQ INT4):必然会影响模型的输出结果。

  • 采样参数:LLM 生成时会加上一些采样策略,以保证生成结果的丰富度,然而这些采样策略都会引入随机性,每次请求的结果会变,因此通常会首先会采用 Greedy Search 来去除随机性,等结果对齐之后再进一步打开引入随机性的采样策略。

  • Batching:LLM 推理中提升吞吐最主要的手段就是通过 Batching 充分发挥 GPU 算力,然而不同的 Batch Size 会导致 LLM 推理时采用不同的 CUDA Kernel(不同的算法),进而导致出现误差,而且 LLM 这种逐个 Token 生成的方式会导致误差累积,结果差异会进一步放大。

在 LLM 推理中,要想保证生成结果的严格对齐通常是很困难的,此时往往需要进一步地全面评估来验证效果。

三、LLM 推理影响因素

3.1 硬件环境

与常规的 AI 模型推理一样,LLM 也可以选择使用 GPU 推理或使用 CPU 推理,与传统 AI 模型不同的是,LLM 模型往往很大,需要大量的存储空间,单个推理实例比常规的 AI 模型大得多。比如一个常见的 13B LLM 为例,使用 FP16 精度,其仅模型参数就需要 13B * 2 = 26GB 的存储空间,甚至很多 GPU 显存(比如 T4 GPU 只有 15GB 可用显存)都不足以装下模型参数,更不用说 KV Cache 等临时存储。此时往往需要采用分布式多卡推理,而一个 T4 GPU 却足以容纳多个 ResNet50 或 Bert Base 模型实例。

此外,LLM 的两阶段推理特性(Prefill 和 Decoding)也为硬件选型带来了很大的挑战和可能,可以从一个 LLM 推理集群的角度去考虑,也可以从 LLM 推理服务或单个 LLM 推理实例的角度去考量硬件配置。

3.1.1 推理集群

微软和华盛顿大学在 [2311.18677] Splitwise: Efficient generative LLM inference using phase splitting 中提出了 Splitwise,作者专门构建了 LLM 推理集群,为 LLM 推理不同阶段选择不同的 GPU 类型,Prefill 阶段为计算密集型,可以选择高算力 GPU,而 Decoding 阶段为访存密集型,相应的可以使用算力不是特别强而访存带宽比较大的 GPU。同时为了两个阶段 KV cache 的共享,需要在 GPU 间有高速的 IB 网络互联。

图片

如下图 Figure 2 所示,在 [2310.18547] Punica: Multi-Tenant LoRA Serving 中,作者针对多租户、多 LoRA LLM 推理场景构建了 LLM 推理集群,以便降低 LLM 推理的成本。

图片

如下图 Figure 3 所示,在 [2311.15566] SpotServe: S

以下是几种主流深度学习框架的功能介绍: 1.PyTorch • 动态计算图:PyTorch采用动态计算图,允许用户在运行时构建和修改计算图,这使得调试和开发更加灵活。 • 自动求导:提供了强大的自动微分机制,能够自动计算梯度,极大地简化了神经网络的训练过程。 • 易用性与灵活性:代码风格接近Python,简洁易懂,与Python数据科学栈(如NumPy)高度集成。 • 分布式训练与混合精度训练:支持多GPU和多节点的分布式训练,以及混合精度训练,可显著加速训练过程。 • 社区支持:拥有活跃的社区和丰富的资源,适合学术研究和工业级应用。 2.TensorFlow • 静态计算图:TensorFlow采用静态计算图,在训练前需要先构建完整的计算图,适合大规模分布式训练和生产级部署。 • TensorBoard可视化:提供了强大的可视化工具TensorBoard,可用于监控训练过程、分析模型性能。 • 丰富的API和工具:支持多种硬件加速,提供了从底层到高层的丰富API,满足不同层次用户的需求。 • 模型部署:通过TensorFlow Serving等工具,可以方便地将模型部署到生产环境中。 3.Keras • 高层API:Keras是一个高层神经网络API,运行在TensorFlow等框架之上,以简单易用、高度模块化著称。 • 快速构建模型:提供了Sequential和Functional API两种模型定义方式,适合快速构建和测试神经网络。 • 数据预处理:内置了多种数据预处理函数,如独热编码、序列填充等。 • 模型评估与调优:支持使用回调函数(如EarlyStopping和学习率调度器)来优化训练过程。 4.其他框架 • Caffe/Caffe2:主要用于计算机视觉任务,支持卷积神经网络(CNN),以高效的训练和推理速度著称。 • MXNet:支持灵活的模型定义和高效的分布式训练,适合大规模数据集。 • PaddlePaddle:百度开发的深度学习框架,支持多种硬件加速,提供了丰富的预训练模型和工具。 • Deeplearning4j:基于Java的深度学习框架,适合在Java生态中使用。 深度学习框架的通用功能 1. 数据预处理:大多数框架提供了数据加载、预处理(如归一化、标准化、数据增强等)的工具。 2. 模型定义:用户可以通过内置的层(如全连接层、卷积层等)快速搭建神经网络。 3. 训练与优化:支持多种优化算法(如SGD、Adam等),并提供自动求导功能。 4. 模型评估与部署:可以对模型进行评估,并通过工具将模型部署到生产环境中。 这些框架各有优势,选择时可以根据具体需求、开发习惯和项目规模来决定。以下是关于大模型搜索引擎和超级计算模板的相关信息: 大模型搜索引擎 1. 博查AI搜索 • 国内首个支持多模型的AI搜索引擎,集成了通义千问、字节云雀、月之暗面Kimi等多个顶尖AI大模型。 • 提供干净、无广告的搜索体验,支持实时信息获取和多模型切换,能够直接生成问题的答案,而非传统搜索引擎的链接列表。 • 其AI智能体深度回答功能(内测中)可提供更丰富、深入的搜索结果。 • 网址:[]()。 2. 秘塔AI搜索 • 能够深入理解用户问题,提供无广告、直达结果的搜索体验。 3. 卡奥斯智能交互引擎 • 专注于工业知识智能搜索和解决方案精准生成,融合智能检索、应用和多模态连续交互功能,以“大连接、大数据、大模型”为基础技术。 4. 360AI搜索 • 结合大模型与搜索技术,注重用户体验,通过多步推理和慢思考模式提高答案质量和准确性。 5. 知乎直答 • 利用知海图AI大模型处理内部文本数据,并整合其他网站文章,生成丰富参考答案。 6. 天工AI搜索 • 搭载天工大模型,提供智能、高效、快速的搜索体验,支持全网信息搜索、智能聚合,并可将结果整理为脑图和大纲。 7. Perplexica • 开源AI驱动搜索引擎,可使用Grok和OpenAI等模型本地运行,适用于学术研究、写作等场景。 8. MindSearch • 基于LLM的多代理框架,通过WebPlanner和WebSearcher模拟人类多步信息寻求和整合过程,能够从大规模网页中并行寻求和整合信息。 超级计算模板 • AI超级计算机 • 专为人工智能应用设计的高性能计算系统,能够处理和分析海量数据,支持复杂的机器学习和深度学习任务。 • 典型应用场景包括语言大模型、视觉大模型和多模态大模型的训练,广泛应用于自动驾驶、智能安防、医学影像等领域。 • 开源AI搜索引擎技术栈 • 一些开源AI搜索引擎(如OpenPerPlex、LangChain-SearXNG等)结合了多种技术,包括语义分块、搜索引擎集成(如SearXNG)、大模型(如Llama 3)和推理引擎(如Groq),为开发者提供了强大的技术框架。 这些工具和平台为大模型的应用和开发提供了丰富的支持,用户可以根据具体需求选择合适的搜索引擎或计算模板。在讨论如何通过编程实现更环保、低排放的生成式AI时,需要从多个方面来考虑“更好”的编程方式。这里的“更好”可以包括更高的效率、更低的能耗、更简洁的代码以及对环境影响的最小化。以下是一些具体的建议和方向: --- 1.选择合适的编程语言 不同的编程语言在性能、开发效率和资源消耗方面各有优劣。对于开发低能耗的AI应用,以下语言可能是较好的选择: Python • 优点: • 丰富的库和框架:Python是深度学习和AI领域的主流语言,拥有大量的开源库(如TensorFlow、PyTorch、Keras等),这些库经过优化,能够高效地利用硬件资源。 • 易读性和开发效率:Python语法简洁,易于理解和维护,适合快速开发和迭代。 • 社区支持:拥有庞大的开发者社区,遇到问题时更容易找到解决方案。 • 优化方向: • 使用高效的Python库(如NumPy、Pandas)进行数据处理。 • 利用JIT编译器(如Numba)加速Python代码的执行。 • 避免不必要的循环和复杂的数据结构,减少内存占用。 C++ • 优点: • 高性能:C++在执行效率上优于Python,尤其是在大规模数据处理和复杂计算任务中。 • 底层控制:能够直接操作硬件资源,适合对性能要求极高的场景。 • 优化方向: • 使用高效的算法和数据结构。 • 利用多线程和并行计算技术充分利用多核CPU。 • 结合CUDA等技术加速GPU计算。 Julia • 优点: • 高性能与易用性:Julia在性能上接近C++,同时语法简洁,类似于Python。 • 内置并行计算支持:Julia原生支持多线程和分布式计算,适合大规模并行任务。 • 优化方向: • 利用Julia的内置并行计算功能,减少计算时间。 • 使用预编译的包和库,避免运行时的性能开销。 --- 2.编程实践中的优化策略 无论选择哪种语言,以下编程实践都能帮助降低能耗和提高效率: 高效的数据处理 • 避免重复计算:缓存中间结果,避免重复执行相同的计算。 • 批量处理:将数据分批处理,减少I/O操作和内存占用。 • 数据压缩:在不影响模型性能的前提下,对数据进行压缩以减少存储和传输成本。 代码优化 • 减少不必要的循环和递归:优化算法复杂度,减少不必要的计算。 • 使用内置函数和库:内置函数通常经过优化,比自定义实现更高效。 • 内存管理:合理管理内存分配和释放,避免内存泄漏。 并行计算 • 多线程和多进程:利用多核CPU的计算能力,将任务分配到多个线程或进程中。 • GPU加速:对于深度学习任务,使用GPU加速可以显著减少计算时间和能耗。 • 分布式计算:对于大规模任务,可以使用分布式计算框架(如Apache Spark)将任务分配到多个节点上。 --- 3.开发环境和工具的选择 • 使用高效的IDE:选择支持代码优化、性能分析和调试的集成开发环境(如PyCharm、Visual Studio Code)。 • 性能分析工具:使用性能分析工具(如Python的cProfile、C++的gprof)来识别代码中的性能瓶颈。 • 代码审查:定期进行代码审查,优化算法和数据结构,减少冗余代码。 --- 4.环境友好型编程的额外建议 • 选择绿色云计算服务:使用采用可再生能源的数据中心,减少碳排放。 • 模型优化:选择更高效的模型架构,避免过度复杂的模型。例如,使用轻量级模型(如MobileNet)代替大型模型。 • 资源管理:合理规划硬件资源,避免过度配置。例如,根据任务需求动态调整GPU资源。 --- 总结 选择“更好”的编程语言和实践需要综合考虑任务需求、开发效率和环境影响。Python是目前AI领域的主流选择,适合快速开发和迭代;C++适合对性能要求极高的场景;Julia则在性能和易用性之间取得了很好的平衡。无论选择哪种语言,通过优化代码、利用并行计算和选择绿色计算资源,都可以显著降低生成式AI的碳排放,实现更环保的编程目标。
03-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值