text-generation-inference 文档

TGI v3 概述

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

TGI v3 概述

总结

性能飞跃:在长提示下,TGI 处理的 token 是 vLLM 的 3 倍,速度快 13 倍。零配置!

tokens 数量增加 3 倍。

通过减少内存占用,我们能够比以前摄取更多 token,也更具动态性。单个 L4 (24GB) 可以在 llama 3.1-8B 上处理 3 万个 token,而 vLLM 几乎只能处理 1 万个。我们在减少运行时占用方面投入了大量工作,其效果在较小的受限环境中最为明显。

速度快 13 倍

在长提示 (20 万以上 token) 对话中,vLLM 的回复需要 27.5 秒,而 TGI 仅需 2 秒。为什么这么快?我们保留了初始对话,因此当有新的回复进来时,我们可以几乎立即回答。查找的开销约为 5 微秒。感谢 @Daniël de Kok 提供的出色数据结构。

零配置

就是这样。删除您正在使用的所有标志,您很可能获得最佳性能。通过评估硬件和模型,TGI 仔细选择自动值以提供最佳性能。在生产环境中,我们的部署中不再有任何标志。我们保留了所有现有的标志,它们在小众场景中可能会派上用场。

基准测试

方法论

为了确保准确可靠的结果,我们采用了稳健的基准测试协议,以解决性能评估中常见的缺陷。具体来说:

  1. 一致的代码:我们使用相同的代码库针对不同的引擎运行,确保任何性能差异都归因于 LLM 本身,而不是测试框架的差异。
  2. 基于请求的测量:我们没有通过尽可能多地发送请求来测量每秒请求数 (RPS),而是选择了一种更一致的方法,即发送固定数量的请求并测量服务器完成所有请求所需的时间。这种方法避免了边界效应,并提供了更准确的性能表示。
  3. 真实的组合:我们选择了 LLM 和硬件配置的真实组合,因此我们对 70B 模型使用了 8xH100,而不是 8B 模型,因为后者会浪费资金。
  4. 真实场景 我们在启用前缀缓存的情况下对引擎进行了基准测试,因此我们报告的是第二次运行的结果,而不是第一次运行的结果。在基准测试的第一次运行时,每个请求都是新的,因此前缀缓存不起作用,掩盖了使用它的真实世界优势。

注意:边界效应是指基准测试结果不稳定,因为其结果取决于被基准测试引擎的细微细节。例如,一个系统以恒定的 10RPS 摄取,但在基准测试中,在基准测试结束前 -0.1 秒收到单个最终请求,并且该单个请求需要整整 10 秒才能处理。那么,一个耗时 30 秒的基准测试将测量 7.5RPS,而不是预期的 10RPS,因为该单个查询没有与其他查询并行化。另一个速度稍慢的引擎会在 +0.1 秒时收到该请求,该请求将被基准测试丢弃,因此将速度较慢的系统测量为速度更快。

有关一般基准测试的更多详细信息,我们建议您阅读 k6 的文档:https://grafana.org.cn/docs/k6/latest/

场景

我们选择了一些场景来简化情况,它们似乎准确地反映了更大的趋势。

  1. 小型场景:此场景包括来自 orca 数据集的前 200 个请求被提示给模型。这 200 个请求总共包含 8k 个 token,代表了对话的开始。前缀缓存在该场景中的影响非常有限,我们认为对于简单的用例来说,这是一个相对平衡的基准测试。

  2. 长场景:此场景包括 20 个请求,总共包含 20 万个提示 token,这些请求本质上是要求对大块文本进行摘要。在实际场景中,当您重复输入大块代码、大块业务数据或文档并询问有关它们的简单问题(摘要、分类或在何处查找某些数据)时,这非常有用。此场景最接近许多专业用例的用途,即在提示本身中包含大量信息。这些非常长的对话是我们最近更改的最大受益者,因为我们能够实现更大的提示和更快的缓存。

    硬件

    1. L4:这是一个单 L4 (24GB),代表小型甚至家庭计算能力。我们在此对其进行了 meta-llama/Meta-Llama-3.1-8B-Instruct 测试。
    2. 4xL4:这是一个更强大的部署,通常用于 8B 模型(正在测试的模型)的超大请求部署,或者也可以轻松处理所有 30GB 模型。对于此基准测试,我们测试了 meta-llama/Meta-Llama-3.1-8B-Instruct
    3. 8xH100 这是可能的最强大的部署之一。我们测试了 meta-llama/Meta-Llama-3.1-70B-Instruct,因为它是此尺寸最具代表性的模型。Llama 3.3 在基准测试时尚未发布(它是完全相同的模型,因此没有任何区别)。

复现结果

运行基准测试的命令如下

  1. 准备数据集
cd text-generation-inference/load_tests
make prepare_orca
python long.py
  1. 启动引擎

TGI: text-generation-launcher --model-id $MODEL_ID --num-shard $N --port 8000 (或 docker 变体) vLLM: vllm serve $MODEL_ID --tensor-parallel $N —enable-prefix-caching (或 docker 变体)

  1. 启动场景:小型:MODEL_ID=$MODEL_ID HOST=localhost:8000 k6 run load_tests/common.js 长型:MODEL_ID=$MODEL_ID HOST=localhost:8000 k6 run load_tests/long.js

结果

benchmarks_v3

我们的基准测试结果显示出显著的性能提升,与启用前缀缓存的 vLLM 相比,速度提高了 13 倍,与未启用前缀缓存的 vLLM 相比,速度提高了 30 倍。这些结果与我们的生产数据一致,并证明了我们优化的 LLM 架构的有效性。

原始结果

第二次运行 TGI v3 (时间,单位:秒) vLLM (秒) 请求数量
Llama 3.1 8b 小型测试 - L4 - 8B 17.5 19.9 200
Llama 3.1 8b 长型测试* - L4 - 8B 53 57 10
Llama 3.1 8b 小型测试 - 4xL4 - 8B 4.8 6 200
Llama 3.1 8b 长型测试 - 4xL4 - 8B 3.2 12.5 20
Llama 3.1 70b 小型测试 - 8XH100 - 70B 6.2 7.4 200
Llama 3.1 70b 长型测试 - 8H100 - 70B 2 27.5 20
第一次运行 TGI (秒) vLLM (秒) 请求数量
Llama 3.1 8b 小型测试 - L4 19.9 19.9 200
Llama 3.1 8b 长型测试 (10) - L4 49.8 55 10
Llama 3.1 8b 小型测试 - 4xL4 13 12.6 200
Llama 3.1 8b 长型测试 - 4xL4 47 50.3 20
Llama 3.1 70b 小型测试 - 8XH100 7.5 7.6 200
Llama 3.1 70b 长型测试 - 8H100 12.1 28.3 20

注意事项和局限性

虽然我们的结果很有希望,但仍有一些注意事项需要考虑:

  1. 受限的 kv-cache:如果部署缺少 kv-cache 空间,则意味着许多查询将需要 kv-cache 的相同槽位,从而导致 kv-cache 中的争用。您可以通过限制 --max-total-tokens 来减少这种影响,以减少单个查询的影响。您还可以使用更多 GPU 或更大的 GPU,以增加 kv-cache 的大小。
  2. 复制:在单个端点后面有多个副本的场景中,没有理由让来自特定用户的每个查询都命中相同的副本,因此缓存将不会存在,这意味着没有速度优势。您可以使用粘性会话负载均衡来强制每个用户将其请求发送到相同的副本。不要盲目应用此操作,这可能根本没有必要。

技术见解

我们的性能提升可归因于以下几个关键因素:

  1. 新内核:我们的自定义内核,包括 flashinferflashdecoding,在长提示长度下提供了更高的性能,并实现了更高效的调度。
  2. 前缀缓存:我们优化的前缀缓存结构允许快速查询匹配,即使对于长提示也是如此。开销大约为 6 微秒。
  3. 分块代码:我们的分块代码可以更精细地控制计算资源,确保最佳性能并减少 VRAM 使用量。
  4. 内核优化:我们实施了各种其他内核优化,包括更好的内核选择。值得注意的是,我们实施了多个小型内核,这些内核参与了查询簿记,在小型模型上尤其高效。每个内核启动都有几毫秒的开销,因此当此簿记相对于原始模型计算很重要时,将它们融合在一起会大大提高性能。这种情况通常发生在特定模型的计算能力过大以及模型特别小的情况下。
  5. VRAM 效率:在超大请求(10 万以上 token)领域,有很多地方开始成为内存消耗大户。我们已经找到了最大的几个,并找到了减少/重用或删除它们的方法。最大的罪魁祸首可能是 logits 计算。llama 3.1-8b 的 Logits 占用 25.6GB (=10 万个 token * 128k 词汇表 * 2(f16)),这比整个模型(16GB)还要大。问题是,一般来说,我们不需要每个提示的 logits,因此我们只是默认删除了它们,并阻止用户可能要求它们。我们认为这没问题,因为它们主要供研究人员使用。您可以使用 --enable-prefill-logprobs 标志再次启用您的部署以拥有它们,但您会体验到 token 提示大小的减少。

未来方向

虽然我们取得了重大进展,但仍有改进的机会:

  1. 特殊模型:所有 LLM 都具有上述改进。某些特定功能可能没有(例如,某些量化、推测或 VLM 更难进行相同程度的详细优化)。
  2. KV-Cache 长期保留:解决 KV-cache 长期保留是一个挑战。我们设想了几种解决方案,例如共享 KV-cache(如 redis 或 memcached)解决方案或创新的存储方法。这是我们正在进行的研究领域。
  3. 多模态模型:我们还在研究很多其他类型的模型,例如音频到音频、图像/视频生成和其他混合模型,在这些模型中,我们看到了应用我们在 TGI 中应用的相同原则以最大化性能的巨大潜力。

通过分享我们的基准测试方法、结果和技术见解,我们旨在为更高效、更有效的 LLM 的持续发展做出贡献。

< > 在 GitHub 上更新