C++ GPT 运行时#
TensorRT-LLM 包含一个 C++ 组件,用于执行使用 Python API 构建的 TensorRT 引擎,如TensorRT-LLM 架构部分所述。该组件称为 C++ 运行时。
C++ 运行时的 API 由cpp/include/tensorrt_llm/runtime
中声明的类和cpp/tensorrt_llm/runtime
中实现的类组成。
即使该文档中描述的不同组件名称中包含 GPT,它们也并非仅限于此特定模型。例如,这些类可用于实现 BLOOM、GPT-J、GPT-NeoX 或 LLaMA 等自回归模型。
对 T5 等编码器-解码器模型的完整支持将在未来的 TensorRT-LLM 版本中添加。目前仅提供 Python 版本的实验性支持,位于examples/enc_dec
文件夹中。
概述#
运行时模型由ModelConfig
类的实例和必须执行的 TensorRT 引擎指针描述以执行推理。环境通过WorldConfig
进行配置(该名称来源于MPI及其“著名”的MPI_COMM_WORLD
默认通信器)。SamplingConfig
类封装了控制新令牌生成的参数。
模型配置#
模型配置是ModelConfig
类的一个实例。该类封装了以下参数(它们被声明为私有成员变量,并通过 getter 和 setter 暴露):
vocabSize
,词汇表大小,numLayers
,模型中的层数,numHeads
,注意力块中的头数,numKvHeads
,注意力组件中 K 和 V 的头数。当 K/V 头数与 (Q) 头数相同时,模型使用多头注意力。当 K/V 头数为 1 时,使用多查询注意力。否则,使用分组查询注意力。有关更多信息,请参阅多头、多查询和分组查询注意力,hiddenSize
,隐藏维度的大小,dataType
,用于构建 TensorRT 引擎并在推理期间运行模型的数据类型,useGptAttentionPlugin
,指示多头、多查询和分组查询注意力运算符是否使用GPT Attention 插件编译,inputPacked
,指示输入必须打包(或设置为false
时进行填充)。出于性能原因,建议始终使用打包,即使其默认值设置为false
(将在未来版本中更改)。有关更多信息,请参阅多头、多查询和分组查询注意力,pagedKvCache
,指示 K/V 缓存是否使用分页。有关更多信息,请参阅多头、多查询和分组查询注意力,tokensPerBlock
,是 K/V 缓存每个块中的令牌数。当启用分页 K/V 缓存时,该参数相关。默认值为 64。有关更多信息,请参阅多头、多查询和分组查询注意力,quantMode
,控制量化方法。有关更多信息,请参阅数值精度。maxBatchSize
,指示 TensorRT 引擎构建时支持的最大批处理大小,maxInputLen
,输入序列的最大大小,maxSequenceLen
,序列的最大总大小(输入+输出)。
World 配置#
使用 TensorRT-LLM C++ 运行时无需熟悉MPI。您需要了解以下两点主要内容:
TensorRT-LLM 中的 C++ 运行时使用进程在不同的 GPU 上执行 TensorRT 引擎。这些 GPU 可以位于单个节点上,也可以位于集群中的不同节点上。每个进程在 MPI 中称为一个 rank。
rank 被分组到通信组中。TensorRT-LLM C++ 运行时将该组称为 world。
World 配置是WorldConfig
类的一个实例,它封装了以下参数:
tensorParallelism
,协作实现张量并行性(TP)的 rank 数。使用 TP 时,每个 GPU 执行模型所有层的计算。其中一些计算在 GPU 之间分布。在大多数情况下,TP 比流水线并行性(PP)更均衡,但需要在 GPU 之间更高的带宽。在 GPU 之间存在 NVLINK 时,建议使用此设置,pipelineParallelism
,协作实现流水线并行性(PP)的 rank 数。使用 PP 时,每个 GPU 处理连续层的一个子集。GPU 之间的通信仅发生在层子集的边界处。使用 PP 更难保证 GPU 的充分利用,但所需的内存带宽更少。在 GPU 之间不存在 NVLINK 时,建议使用此设置,rank
,rank 的唯一标识符,gpusPerNode
,指示每个节点上的 GPU 数量。拥有此信息使 C++ 运行时能够优化节点内 GPU 之间的通信(例如利用 A100 DGX 节点中 GPU 之间的NVLINK互连)。
采样参数#
SamplingConfig
类封装了控制新令牌生成的参数。下表列出了选择解码方法的比较(X
表示尚不支持)。除了beamWidth
参数外,所有字段都是可选的,如果用户未提供值,运行时将使用默认值。对于向量字段,TensorRT-LLM 运行时支持每个序列一个值(即向量包含batchSize
个值)。如果所有序列对给定参数使用相同的值,则向量可以限制为单个元素(即size() == 1
)。
HF 中的方法名称 |
HF 中的条件 |
TRT-LLM 中的方法名称 |
TRT-LLM 中的条件 |
---|---|---|---|
辅助解码 |
|
X |
|
集束搜索解码 |
|
集束搜索 |
|
集束搜索多项式采样 |
|
X |
|
受约束集束搜索解码 |
|
X |
|
对比搜索 |
|
X |
|
多样化集束搜索解码 |
|
X |
|
贪婪解码 |
|
采样 |
|
多项式采样 |
|
采样 |
|
常规
TRT-LLM 中的名称 |
描述 |
数据类型 |
值范围 |
默认值 |
HF 中的名称 |
---|---|---|---|---|---|
|
采样工作流程中 logits 的调制 |
List[Float] |
[0.0f, $+\infty$) |
|
|
|
生成令牌数量的下界 |
List[Int] |
[0, $+\infty$) |
|
|
|
惩罚重复令牌 |
List[Float] |
[0.0f, $+\infty$) |
|
|
|
惩罚已存在的令牌 |
List[Float] |
($-\infty$, $+\infty$) |
|
no |
|
惩罚已存在的令牌 |
List[Float] |
($-\infty$, $+\infty$) |
|
no |
|
List[Int] |
[0, $+\infty$) |
|
|
在将
repetitionPenalty
、presencePenalty
和frequencyPenalty
应用到 logits 时,输入提示的令牌会被包含在内。参数
repetitionPenalty
、presencePenalty
和frequencyPenalty
不是互斥的。
采样
TRT-LLM 中的名称 |
描述 |
数据类型 |
值范围 |
默认值 |
HF 中的名称 |
---|---|---|---|---|---|
|
随机数生成器的随机种子 |
Int64 |
[0, 2^64-1] |
|
no |
|
用于采样的 logits 数量 |
List[Int] |
[0, 1024] |
|
|
|
用于采样的 top-P 概率 |
List[Float] |
[0.0f, 1.0f] |
|
|
|
topP 算法中的衰减 |
List[Float] |
(0.0f, 1.0f] |
|
no |
|
topP 算法中的衰减 |
List[Float] |
(0.0f, 1.0f] |
|
no |
|
topP 算法中的衰减 |
List[Int] |
[-1, $+\infty$) |
|
no |
|
缩放最可能的令牌以确定最小令牌概率。 |
List[Float] |
[0.0f, 1.0f] |
|
|
如果设置
topK = 0
且topP = 0.0f
,则执行贪婪搜索。如果设置
topK > 0
且topP = 0.0f
,则概率最高的topK
个令牌将成为采样的候选(在 TRT-LLM 中称为TopK sampling
)。如果设置
topK = 0
且topP > 0.0f
,令牌将按概率降序排序,然后累积概率大于topP
的概率最高的令牌将成为采样的候选(在 TRT-LLM 中称为TopP sampling
)。如果设置
topK > 0
且topP > 0.0f
,则将选择概率最高的topK
个令牌,然后将这些选定的令牌按概率降序排序并将其概率归一化,然后累积概率大于topP
的归一化概率最高的令牌将成为采样的候选(在 TRT-LLM 中称为TopKTopP sampling
)。如果批处理中不同序列提供了不同的
topK
值,则实现的性能将取决于最大值。出于效率原因,建议将具有相似topK
值的请求一起进行批处理。topPDecay
、topPMin
和topPResetIds
在用于开放式文本生成的真实性增强语言模型中进行了解释。topPDecay
是衰减,topPMin
是下界,topPResetIds
指示重置衰减的位置。minP
在升温:Min-p 采样用于创意和连贯的 LLM 输出中进行了解释。
集束搜索
TRT-LLM 中的名称 |
描述 |
数据类型 |
值范围 |
默认值 |
HF 中的名称 |
---|---|---|---|---|---|
|
集束搜索算法的宽度 |
Int |
[0, 1024] |
|
|
|
生成令牌的多样性 |
List[Float] |
[0, $+\infty$) |
|
|
|
惩罚更长的序列 |
List[Float] |
[0, $+\infty$) |
|
|
|
参见下方描述 |
List[Int] |
($-\infty$, $+\infty$) |
|
|
集束搜索算法:集束搜索。
HF 中的参数
diversity_penalty
仅用于多样化集束搜索解码
(或称为Group-Beam-Search
),TRT-LLM 尚未支持该功能。如果设置
earlyStopping = 1
,则一旦生成了beamWidth
个完成句子,解码将停止。如果设置
earlyStopping = 0
,则解码将继续进行,直到无法生成更好的句子(得分更高)。如果将
earlyStopping
设置为其他值,则解码将仅取决于lengthlengthPenalty
。beamWidth
参数是一个标量值。这意味着在 TensorRT-LLM 的当前版本中,无法为每个输入序列指定不同的宽度。此限制可能会在未来版本中解除。
会话#
运行时会话已被弃用,推荐使用执行器 API。它将在 TensorRT-LLM 的未来版本中移除。
GptSession 用于运行 GPT 类自回归模型的示例可在cpp/tests/runtime/gptSessionTest.cpp
中找到。
内部组件#
GptSession
类封装了两个主要组件。TllmRuntime
负责执行 TensorRT 引擎。GptDecoder
从 logits 生成令牌。TllmRuntime
类是一个内部组件,不建议直接使用该类。GptDecoder
可以直接用于实现自定义生成循环,以及用于GptSession
实现无法满足的用例。
In-flight Batching 支持#
In-flight batching 通过为每个请求使用单独的解码器来支持。与使用单个解码器相比,最大的区别在于如何管理从 logits 生成令牌。一个批处理被拆分成batchSize
个单独的请求,并使用分开的 CUDA 流发出内核。此行为可能会在未来版本中重新考虑,以维护批处理的结构并提高效率。
已知问题和未来变更#
在当前版本的 TensorRT-LLM 中,C++ 和 Python 运行时是两个独立的软件组件,并且 C++ 运行时正在更积极地开发(包括 in-flight batching 等功能)。未来版本的目标可能是基于 C++ 运行时重建 Python 运行时。