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,表示Multi-Head, Multi-Query, and Group-Query Attention操作符是否使用了GPT Attention插件进行编译,

  • inputPacked,表示输入必须被打包(或在设置为false时进行填充)。出于性能考虑,建议始终使用打包,即使其默认设置为false(将在未来的版本中更改)。更多信息请参考多头、多查询和组查询注意力

  • pagedKvCache,表示K/V缓存是否使用分页。 更多信息请参考多头、多查询和组查询注意力

  • tokensPerBlock,是K/V缓存中每个块的令牌数量。 当启用分页K/V缓存时,它是相关的。默认情况下,该值为64。有关更多信息,请参阅多头、多查询和组查询注意力

  • quantMode,控制量化方法。更多信息请参考数值精度

  • maxBatchSize,表示TensorRT引擎构建时的最大批量大小,

  • maxInputLen,输入序列的最大长度,

  • maxSequenceLen,序列的最大总大小(输入+输出)。

世界配置

熟悉 MPI 不是使用 TensorRT-LMM C++ 运行时的必要条件。你需要知道的主要有两点:

  • TensorRT-LLM中的C++运行时使用 进程来在不同的GPU上执行 TensorRT引擎。这些GPU可以位于单个节点上,也可以位于集群中的不同节点上。每个进程在MPI中被称为 rank

  • 排名按通信组进行分组。TensorRT-LLM C++ 运行时调用将该组称为 world

世界配置是 WorldConfig 类的一个实例,它封装了以下参数:

  • tensorParallelism,协作实现张量并行(TP)的等级数量。使用TP时,每个GPU执行模型所有层的计算。其中一些计算分布在GPU之间。在大多数情况下,TP比管道并行(PP)更平衡,但需要GPU之间更高的带宽。在GPU之间存在NVLINK的情况下,这是推荐的设置。

  • pipelineParallelism,协作实现管道并行(PP)的等级数量。使用PP时,每个GPU处理一组连续的层。GPU之间的通信仅在层的子集边界处发生。使用PP时,很难保证GPU的完全利用率,但它需要的内存带宽较少。在没有GPU之间的NVLINK的情况下,这是推荐的设置。

  • rank,排名的唯一标识符,

  • gpusPerNode,表示每个节点上的GPU数量。拥有这些信息可以让C++运行时优化节点内GPU之间的通信(例如利用A100 DGX节点中GPU之间的NVLINK互连优势)。

采样参数

SamplingConfig 类封装了控制新令牌生成的参数。选择解码方法的比较如下表所示(X 表示尚未支持)。除了 beamWidth 参数外,所有字段都是可选的,如果用户未提供值,运行时将使用默认值。对于向量字段,TensorRT-LLM 运行时支持每个序列一个值(即向量包含 batchSize 个值)。如果所有序列对给定参数使用相同的值,则向量可以限制为单个元素(即 size() == 1)。

HF中的方法名称

HF中的条件

TRT-LLM中的方法名称

TRT-LLM中的条件

辅助解码

assistant_modelprompt_lookup_num_tokens!=None

X

束搜索解码

num_beams>1do_sample=False

束搜索

beamWidth > 1

波束搜索多项式采样

num_beams>1do_sample=True

X

受限束搜索解码

constraints!=Noneforce_words_ids!=None

X

对比搜索

penalty_alpha>0top_k>1

X

多样化的束搜索解码

num_beams>1num_beam_groups>1

X

贪婪解码

num_beams=1do_sample=False

采样

beamWidth == 1topK=0 以及 topP=0.0f

多项式采样

num_beams=1do_sample=True

采样

beamWidth == 1 并且 (topK>0topP>0.0f)

通用

TRT-LLM中的名称

描述

数据类型

值的范围

默认值

HF中的名称

temperature

采样工作流中对logits的调制

浮点数列表

[0.0f, $+\infty$)

1.0f (无调制)

temperature

minLength

生成的令牌数量的下限

整数列表

[0, $+\infty$)

0 (无效果(第一个生成的标记可以是EOS)

min_length

repetitionPenalty

惩罚重复的标记
乘法方式,不考虑出现次数

浮点数列表

[0.0f, $+\infty$)
< 1.0f 鼓励重复
> 1.0f 不鼓励重复

1.0f(无效果)

repetition_penalty

presencePenalty

惩罚已存在的令牌
加法,不论出现次数

浮点数列表

($-\infty$, $+\infty$)
< 0.0f 鼓励重复
> 0.0f 阻止重复

0.0f (无效果)

frequencyPenalty

惩罚已存在的令牌
加法,依赖于出现次数

浮点数列表

($-\infty$, $+\infty$)
< 0.0f 鼓励重复
> 0.0f 阻止重复

0.0f (无效果)

noRepeatNgramSize

整数列表

[0, $+\infty$)
> 0 该大小的所有ngram只能出现一次

0 (无效果)

no_repeat_ngram_size

  • 在将repetitionPenaltypresencePenaltyfrequencyPenalty应用于logits时,输入提示的tokens被包含在内。

  • 参数 repetitionPenalty, presencePenalty, 和 frequencyPenalty 并不相互排斥。

采样

TRT-LLM中的名称

描述

数据类型

值的范围

默认值

HF中的名称

randomSeed

随机数生成器的随机种子

Int64

[0, 2^64-1]

0

topK

从中采样的logits数量

整数列表

[0, 1024]

0

top_k

topP

从中采样的最高P概率

浮点数列表

[0.0f, 1.0f]

0.0f

top_p

topPDecay

topP算法中的衰减

浮点数列表

(0.0f, 1.0f]

1.0f

topPMin

topP 算法中的衰减

浮点数列表

(0.0f, 1.0f]

1.0e-6,f

topPResetIds

topP 算法中的衰减

整数列表

[-1, $+\infty$)

-1(无效果)

  • 如果设置 topK = 0topP = 0.0f,则执行贪婪搜索。

  • 如果设置topK > 0并且topP = 0.0ftopK个最高概率的标记将成为采样的候选(在TRT-LLM中称为TopK sampling)。

  • 如果设置topK = 0topP > 0.0f,令牌将按概率降序排序,然后累积概率大于topP的最高概率令牌将成为采样的候选(在TRT-LLM中称为TopP sampling)。

  • 如果设置topK > 0topP > 0.0f,将选择概率最高的topK个标记,然后这些选定的标记将按概率降序排序,并且它们的概率将被归一化,然后归一化概率最高的标记,其累积概率大于topP的标记将成为采样的候选(在TRT-LLM中称为TopKTopP sampling

  • 如果为批次中的不同序列提供了不同的topK值,实现的性能将取决于最大的值。出于效率考虑,我们建议将具有相似topK值的请求批次处理在一起。

  • topPDecaytopPMintopPResetIdsFactuality Enhanced Language Models for Open-Ended Text Generation 中有解释。 topPDecay 是衰减率,topPMin 是下限,topPResetIds 表示在哪里重置衰减。

Beam-search

TRT-LLM中的名称

描述

数据类型

值的范围

默认值

HF中的名称

beamWidth

beam-search算法的宽度

整数

[0, 1024]

0 (禁用束搜索)

beam_width

beamSearchDiversityRate

生成标记的多样性

浮点数列表

[0, $+\infty$)

0.0f

diversity_penalty

lengthPenalty

惩罚较长的序列

浮点数列表

[0, $+\infty$)

0.0f

length_penalty

earlyStopping

请参阅以下描述

整数列表

($-\infty$, $+\infty$)

0

early_stopping

  • Beam-search算法: beam search.

  • 参数 diversity_penalty 在 HF 中仅用于 diverse beam-search decoding(或称为 Group-Beam-Search),TRT-LLM 目前还不支持此功能。

  • 如果设置 earlyStopping = 1,一旦生成 beamWidth 个完成的句子,解码将停止。

  • 如果设置earlyStopping = 0,解码将继续进行,直到无法生成更好的句子(具有更高的分数)。

  • 如果将earlyStopping设置为其他值,解码将仅取决于lengthlengthPenalty

  • beamWidth 参数是一个标量值。这意味着在 TensorRT-LLM 的这个版本中,无法为每个输入序列指定不同的宽度。这个限制可能会在未来的版本中被移除。

会话

运行时会话已被弃用,推荐使用Executor API。 它将在未来的TensorRT-LLM版本中被移除。

一个关于如何使用GptSession来运行类似GPT的自回归模型的示例可以在 cpp/tests/runtime/gptSessionTest.cpp中找到。

内部组件

GptSession 类封装了两个主要组件。TllmRuntime 负责执行 TensorRT 引擎。GptDecoder 负责从 logits 生成 tokens。TllmRuntime 类是一个内部组件,您不需要直接使用该类。GptDecoder 可以直接用于实现自定义生成循环,以及用于 GptSession 中的实现无法满足的用例。

飞行中批处理支持

支持使用每个请求的独立解码器进行飞行中的批处理。与使用单个解码器相比,最大的区别在于如何管理从logits生成的令牌。一个批次被分割成batchSize个独立请求,并使用独立的CUDA流发出内核。这种行为可能会在未来的版本中重新审视,以保持批次的结构并提高效率。

已知问题和未来变更

  • 在当前版本的TensorRT-LLM中,C++和Python运行时是两个独立的软件组件,C++运行时正在更积极地开发(具有如飞行批处理等功能)。未来的一个目标可能是在C++运行时的基础上重建Python运行时。