text-generation-inference 文档
TGI v3 概览
并获得增强的文档体验
开始使用
TGI v3 概览
总结
性能飞跃:TGI 处理的 token 数量是 vLLM 的 3 倍,在长提示语上速度快 13 倍。零配置!
3 倍的 token 数量。
通过减少内存占用,我们能够比以前更动态地摄取更多的 token。单个 L4 (24GB) 可以在 llama 3.1-8B 上处理 30k token,而 vLLM 只能处理不到 10k。我们付出了大量努力来减少运行时内存占用,其效果在较小的受限环境中表现最佳。
快 13 倍
在长提示语(200k+ token)上,对话回复在 vLLM 中需要 27.5 秒,而在 TGI 中仅需 2 秒。这是怎么做到的?我们保留了初始对话,因此当新的回复进来时,我们几乎可以立即回答。查找的开销约为 5 微秒。感谢 @Daniël de Kok 提供了这个强大的数据结构。
零配置
就是这样。删除你正在使用的所有标志,你很可能会获得最佳性能。通过评估硬件和模型,TGI 会仔细选择自动值以提供最佳性能。在生产中,我们的部署中不再有任何标志。我们保留了所有现有标志,它们在特殊场景中可能派上用场。
基准测试
方法论
为确保结果准确可靠,我们采用了稳健的基准测试协议,解决了性能评估中的常见陷阱。具体来说:
- 代码一致性:我们使用相同的代码库来针对不同的引擎运行,确保任何性能差异都归因于 LLM 本身,而不是测试框架中的变体。
- 基于请求的度量:我们没有通过发送尽可能多的请求来测量每秒请求数 (RPS),而是选择了一种更一致的方法,即发送固定数量的请求并测量服务器完成所有请求所需的时间。这种方法避免了边界效应,并提供了更准确的性能表示。
- 实际组合:我们选择了 LLM 和硬件配置的实际组合,因此我们为 70B 模型使用了 8xH100,而不是 8B 模型,因为这将是浪费金钱。
- 实际场景:我们对启用前缀缓存的引擎进行了基准测试,因此我们报告的是第二次运行的结果,而不是第一次运行的结果。在基准测试的第一次运行中,每个请求都是新的,因此前缀缓存不起作用,这会掩盖使用它的实际好处。
注意:边界效应是指基准测试结果不稳定,因为它取决于被测试引擎的细微细节。例如,一个系统每秒摄取 10 个 RPS,但在基准测试结束前 0.1 秒收到了一个最终请求,而这个请求需要整整 10 秒才能处理。那么一个耗时 30 秒的基准测试将测量到 7.5 RPS 而不是预期的 10 RPS,因为那个单一查询没有与其他查询并行化。另一个稍慢的引擎将在 0.1 秒后收到该请求,该请求将被基准测试丢弃,从而测量到较慢的系统反而更快。
有关基准测试的更多详细信息,我们建议查阅 k6 文档:https://grafana.org.cn/docs/k6/latest/。
场景
我们选择了一些场景来简化描述,它们似乎准确地反映了更大的趋势。
小型场景:此场景包括来自 orca 数据集的前 200 个请求,这些请求被提示给模型。这 200 个请求总共 8k 个 token,代表了对话的开端。前缀缓存在此场景中影响非常有限,我们认为这是一个相对平衡的简单用例基准测试。
长场景:此场景包含 20 个请求,总计 200k 个提示 token,主要用于总结大块文本。在实际场景中,当您反复输入大块代码、大块业务数据或文档并询问简单问题(摘要、分类或在哪里可以找到某些数据)时,这非常有用。这个场景最接近许多专业用例,因为它在提示本身中包含了大量信息。这些非常长的对话受益于我们最近的更改,因为我们支持更大的提示和更快的缓存。
硬件
L4
:这是单个 L4(24GB),代表小型甚至家庭计算能力。我们测试了meta-llama/Meta-Llama-3.1-8B-Instruct
。4xL4
:这是一种更强大的部署,通常用于 8B 模型(正在测试的模型)的超大型请求部署,或者它可以轻松处理所有 30GB 模型。在此基准测试中,我们测试了meta-llama/Meta-Llama-3.1-8B-Instruct
。8xH100
:这是可能的最强大的部署之一。我们测试了meta-llama/Meta-Llama-3.1-70B-Instruct
,因为它是该尺寸最具代表性的模型。Llama 3.3 在基准测试时尚未发布(它是完全相同的模型,因此没有区别)。
复现结果
运行基准测试的命令如下
- 准备数据集
cd text-generation-inference/load_tests
make prepare_orca
python long.py
- 启动引擎
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 版本)
- 开始场景:小型:
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
结果
我们的基准测试结果显示了显著的性能提升,在使用前缀缓存时比 vLLM 快 13 倍,在不使用前缀缓存时最多快 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 |
注意事项和限制
尽管我们的结果令人鼓舞,但仍有一些注意事项需要考虑
- 受限的 kv-cache:如果部署缺少 kv-cache 空间,这意味着许多查询将需要相同的 kv-cache 插槽,从而导致 kv-cache 争用。您可以通过限制
--max-total-tokens
来减少单个查询的影响。您还可以使用更多的 GPU 或更大的 GPU 来增加 kv-cache 的大小。 - 副本:在单个端点后存在多个副本的场景中,来自特定用户的每个查询都没有理由命中同一副本,因此缓存将不存在,这意味着没有速度优势。您可以使用粘性会话负载平衡来强制每个用户将其请求发送到同一副本。请勿盲目应用此方法,这可能根本没有必要。
技术见解
我们的性能提升可归因于以下几个关键因素
- 新内核:我们的自定义内核,包括
flashinfer
和flashdecoding
,在长提示长度下提供改进的性能,并实现更高效的调度。 - 前缀缓存:我们优化的前缀缓存结构即使对于长提示也能实现快速查询匹配。开销约为 6 微秒。
- 分块代码:我们的分块代码能够更精细地控制计算资源,确保最佳性能并减少 VRAM 使用。
- 内核优化:我们实施了各种其他内核优化,包括更好的内核选择。值得注意的是,我们实施了几个涉及查询簿记的小内核,这些内核在小型模型上特别高效。每个内核启动都有几毫秒的开销,因此将它们融合在一起可以大大提高性能,当这种簿记相对于原始模型计算很重要时。这通常发生在特定模型的超大计算和特别小的模型上。
- VRAM 效率:在处理超大请求(100k+ token)时,许多地方会开始成为巨大的内存消耗者。我们找出了最大的几个,并找到了减少/重用或删除它们的方法。最大的罪魁祸首可能是
logits
计算。Llama 3.1-8b 的 Logits 占用 25.6GB(=100k token * 128k 词汇 * 2 (f16)),这比整个模型 16GB 还要多。问题是,通常我们不需要每个提示的 logits,所以我们默认简单地删除了它们,并阻止用户潜在地请求它们。我们认为这没关系,因为它们主要由研究人员使用。您可以使用--enable-prefill-logprobs
标志再次启用部署以拥有它们,但您将体验到 token 提示大小的减少。
未来方向
虽然我们取得了显著进展,但仍有改进的空间
- 特殊模型:所有 LLM 都具有上述改进。某些特定功能集可能没有(例如,某些量化、推测或 VLM 更难以相同程度的细节进行优化)。
- KV 缓存长期保留:解决 KV 缓存长期保留是一个挑战。目前设想了几种解决方案,例如共享 KV 缓存(如 redis 或 memcached)解决方案或创新的存储方法。这是我们正在进行的研究领域。
- 多模态模型:我们还在大量研究其他类型的模型,如音频到音频、图像/视频生成以及其他混合模型,我们认为这些模型在应用我们在 TGI 中应用的相同原理以最大化性能方面具有巨大潜力。
通过分享我们的基准测试方法、结果和技术见解,我们旨在为更高效、更有效的 LLM 的持续发展做出贡献。
< > 在 GitHub 上更新