基准测试文本生成推理
在本博客中,我们将探讨 Text Generation Inference (TGI) 的小兄弟,即 TGI 基准测试工具。它将帮助我们了解如何超越简单的吞吐量来分析 TGI,从而更好地理解权衡取舍,以便根据您的需求调整部署。如果您曾觉得 LLM 部署成本过高,或者您想调整部署以提高性能,那么这篇博客适合您!
我将向您展示如何在便捷的 Hugging Face Space 中完成此操作。您可以将结果用于 推理端点 或相同硬件的其他副本。
动机
为了更好地理解分析的必要性,我们先讨论一些背景信息。
大型语言模型(LLM)从根本上讲效率不高。根据 解码器的工作方式,每次生成都需要为每个解码的 token 进行一次新的前向传播。随着 LLM 规模的增大,以及企业 采用率的飙升,人工智能行业在创建新的优化和性能增强技术方面做得非常出色。
在 LLM 服务方面,已经有了数十项改进。我们看到了 Flash Attention、Paged Attention、流式响应、批处理改进、推测解码、各种 量化、Web 服务器改进、采用 更快的语言(抱歉 Python 🐍)等等。还有一些用例改进,如 结构化生成 和 水印,它们现在在 LLM 推理世界中占有一席之地。问题在于,快速高效的实现需要越来越专业的技能才能实现 [1]。
Text Generation Inference 是 Hugging Face 的高性能 LLM 推理服务器,旨在采用和开发最新的技术,以改进 LLM 的部署和使用。由于 Hugging Face 的开源合作伙伴关系,大多数(如果不是全部)主要的开源 LLM 在发布当天即可在 TGI 中使用。
用户通常会根据其用例要求有非常不同的需求。考虑 RAG 用例 中的提示和生成:
- 指令/格式
- 通常很短,<200 个 token
- 用户查询
- 通常很短,<200 个 token
- 多个文档
- 中等大小,每个文档 500-1000 个 token,
- N 个文档,其中 N<10
- 输出中的答案
- 中等大小,约 500-1000 个 token
在 RAG 中,拥有正确的文档对于获得高质量响应至关重要,您可以通过增加包含更多文档的 N 来增加这种可能性。这意味着 RAG 通常会尝试最大化 LLM 的上下文窗口以提高任务性能。相比之下,考虑基本聊天。典型的 聊天场景 的 token 数量明显少于 RAG:
- 多轮对话
- 2xTx50-200 token,T 轮
- 2x 表示用户和助手
鉴于我们有如此不同的场景,我们需要确保根据哪个场景更相关来相应地配置我们的 LLM 服务器。Hugging Face 有一个 基准测试工具 可以帮助我们探索哪些配置最合理,我将解释如何在 Hugging Face Space 上完成此操作。
先决条件
在我们深入了解工具之前,让我们确保我们对一些关键概念有共同的理解。
延迟与吞吐量
图 1:延迟与吞吐量可视化 |
- Token 延迟 – 处理并向用户发送 1 个 token 所需的时间
- 请求延迟 – 完全响应一个请求所需的时间
- 首次 Token 时间 - 从初始请求到第一个 token 返回给用户的时间。这是处理预填充输入和单个生成 token 所需时间的组合。
- 吞吐量 – 服务器在设定时间内可以返回的 token 数量(在此示例中为每秒 4 个 token)
延迟是一个棘手的衡量标准,因为它不能说明全貌。您的生成可能很长,也可能很短,这对于您的实际服务器性能而言意义不大。
重要的是要理解吞吐量和延迟是正交的度量,并且根据我们配置服务器的方式,我们可以针对其中一个进行优化。我们的基准测试工具将通过数据可视化帮助我们理解这种权衡。
预填充和解码
![]() |
---|
图 2:预填充与解码(灵感来自 [2]) |
这是 LLM 生成文本的简化视图。模型(通常)为每次前向传播生成一个 token。在橙色的 预填充阶段,完整提示(What is.. of the US?)被发送到模型并生成一个 token(Washington)。在蓝色的 解码阶段,生成的 token 被附加到前一个输入中,然后此(... the capital of the US? Washington)被发送到模型中进行另一次前向传播。直到模型生成序列结束 token (
点击显示答案
我们不需要生成“What is the”之后的内容。我们知道用户输入的是“capital”。我只包含了一个简短的示例用于说明目的,但请注意,预填充只需要对模型进行一次前向传播,而解码可能需要数百次甚至更多。即使在我们的短示例中,我们也可以看到蓝色箭头多于橙色箭头。现在我们可以明白为什么从 LLM 获取输出需要花费这么多时间了!由于多次前向传播,解码通常是我们花费更多时间思考的部分。
基准测试工具
动机
我们都见过工具、新算法或模型的吞吐量比较。虽然这是 LLM 推理故事的重要组成部分,但它缺少一些关键信息。至少(当然您可以更深入地研究),我们需要知道吞吐量和延迟才能做出好的决策。TGI 基准测试工具的主要优势之一就是它具有这种能力。
另一个重要的思路是考虑您希望用户获得什么样的体验。您更关心服务于许多用户,还是希望一旦用户与您的系统交互就能获得快速响应?您是希望有更好的首次 Token 时间(TTFT),还是希望一旦用户获得第一个 Token 即使第一个 Token 延迟了,也能有飞快的 Token 生成速度?
以下是一些可能的情况。请记住,没有免费的午餐。但是,只要有足够的 GPU 和适当的配置,您几乎可以获得任何想要的体验。
我关心… | 我应该关注… |
处理更多用户 | 最大化吞吐量 |
用户不离开我的页面/应用 | 最小化 TTFT |
适量用户的用户体验 | 最小化延迟 |
全面均衡的体验 | 限制延迟并最大化吞吐量 |
设置
基准测试工具随 TGI 一起安装,但您需要访问服务器才能运行它。考虑到这一点,我提供了这个空间 derek-thomas/tgi-benchmark-space,它结合了 TGI Docker 镜像(固定到最新版本)和 Jupyter Lab 工作空间。它被设计为可复制的,所以如果它处于休眠状态,请不要担心。它将允许我们部署一个我们选择的模型,并通过 CLI 轻松运行基准测试工具。我添加了一些笔记本,可以让您轻松地跟着操作。欢迎深入了解 Dockerfile,了解它是如何构建的,特别是如果您想对其进行调整。
开始
请注意,由于其交互性,最好在 Jupyter Lab 终端而不是笔记本中运行基准测试工具,但我会将命令放在笔记本中,以便我可以进行注释并易于跟随。
- 点击:
- 在 `JUPYTER_TOKEN` 空间密钥 中设置您的默认密码(复制时应提示您)
- 选择您的硬件,请注意它应该与您想要部署的硬件相同。
- 前往您的空间并使用密码登录
- 启动 `01_1_TGI-launcher.ipynb`
- 这将使用 Jupyter 笔记本启动默认设置的 TGI。
- 启动 `01_2_TGI-benchmark.ipynb`
- 这将启动带有演示设置的 TGI 基准测试工具。
主要组成部分
- 组件 1:批次选择器及其他信息。
- 使用箭头选择不同的批次
- 组件 2 和 组件 4:预填充统计信息和直方图
- 计算出的统计数据/直方图基于 `—runs` 的次数。
- 组件 3 和 组件 5:预填充吞吐量与延迟散点图
- X 轴是延迟(越小越好)
- Y 轴是吞吐量(越大越好)
- 图例显示了我们的批处理大小。
- 一个“理想”点将位于左上角(低延迟和高吞吐量)。
理解基准测试工具
如果您使用与我相同的硬件和设置,您应该会得到与图 4 非常相似的图表。基准测试工具向我们展示了在启动 TGI 时给定的当前设置和硬件下,不同批次大小(用户请求的数量,与我们启动 TGI 时的语言略有不同)的吞吐量和延迟。了解这一点很重要,因为我们应该根据基准测试工具的发现来更新我们启动 TGI 的设置。
组件 3 中的图表在预填充较长时(例如 RAG)往往更有趣。它确实会影响 TTFT(显示在 X 轴上),这是用户体验的重要组成部分。请记住,即使我们必须从头开始构建 KV 缓存,我们也可以在一个前向传播中推送输入 token。因此,在许多情况下,它每个 token 的速度通常比解码快。
组件 5 中的图表是我们在解码时的情况。让我们看看数据点的形状。我们可以看到,对于批处理大小为 1-32 的情况,形状大部分是垂直的,大约在 5.3 秒。这非常好。这意味着在不降低延迟的情况下,我们可以显著提高吞吐量!那么 64 和 128 会发生什么呢?我们可以看到,虽然吞吐量在增加,但我们开始牺牲延迟。
对于这些相同的值,让我们看看 组件 3 中的图表发生了什么。对于批处理大小为 32 的情况,我们看到 TTFT 仍然约为 1 秒。但是我们确实开始看到从 32 -> 64 -> 128 的线性增长,批处理大小增加 2 倍,延迟也增加 2 倍。此外,吞吐量没有增加!这意味着我们并没有从这种权衡中获得太多好处。
- 如果我们添加更多点,你期望这些曲线会呈现出什么形状?
- 如果您的令牌数量增加(预填充或解码),您预计这些曲线会如何变化?
如果您的批处理大小处于垂直区域,这很好,您可以免费获得更多吞吐量并处理更多用户。如果您的批处理大小处于水平区域,这意味着您受到计算限制,增加用户只会延迟所有人而没有吞吐量的好处。您应该改进您的 TGI 配置或扩展您的硬件。
既然我们对 TGI 在各种场景下的行为有了一些了解,我们就可以尝试不同的 TGI 设置并再次进行基准测试。在决定一个好的配置之前,最好重复这个循环几次。如果足够感兴趣,我们也许可以推出第二部分,深入探讨聊天或 RAG 等用例的优化。
总结
跟踪实际用户行为很重要。当我们估算用户行为时,我们必须从某个地方开始并做出有根据的猜测。这些数字选择将对我们如何进行分析产生重大影响。幸运的是,TGI 可以在日志中告诉我们这些信息,所以一定要也去查看一下。
完成探索后,请务必停止所有运行,以免产生额外费用。
- 在 `TGI-launcher.ipynb` Jupyter Notebook 中终止正在运行的单元格
- 在终端中按 `q` 键停止分析工具。
- 在空间的设置中点击暂停
结论
LLM 庞大且昂贵,但有多种方法可以降低成本。只要我们正确利用其功能,像 TGI 这样的 LLM 推理服务器就已经为我们做了大部分工作。第一步是了解正在发生什么以及您可以做出哪些权衡。我们已经看到了如何使用 TGI 基准测试工具来做到这一点。我们可以将这些结果用于 AWS、GCP 或推理端点上的任何等效硬件。
感谢 Nicolas Patry 和 Olivier Dehaene 创建了 TGI 及其 基准测试工具。还要特别感谢 Nicholas Patry、Moritz Laurer、Nicholas Broad、Diego Maniloff 和 Erik Rignér 的宝贵校对。
参考文献
[2] : Pierre Lienhart, LLM 推理系列:2. LLM 响应背后的两阶段过程, 2023