LLM 的困惑度指标定义及其计算
困惑度是评价语言模型生成质量的重要参考指标之一,本文将从概念到公式到代码全方位展示如何计算一个语言模型的困惑度,这将有助于我们在特定任务上定量地评估某个 LLM 的生成质量,以及模型量化后的质量损失。
离散型随机变量的概率质量函数以及累计分布函数
设一个离散型随机变量 \(X\) 的概率质量函数为 \(p(x)\),也就是说对于任意的 \(x_i \in \mathcal{X}\),\(P(X = x_i) = p(x_i)\),其中 \(\mathcal{X}\) 是 \(X\) 的样本空间。那么 \(X\) 的累计分布函数 \(F_X(x)\) 定义为
\[F_X(x) = P(X \leq x) = \sum_{x_i \leq x} p(x_i)\]
或者反过来,如果已...
点我阅读更多...
TensorRT 使用指南(4):SadTalker 模型加速方案
介绍
SadTalker 是一个 face reenactment 项目,来自论文 SadTalker: Learning Realistic 3D Motion Coefficients for Stylized Audio-Driven Single Image Talking Face Animation。本文不研究具体的算法原理,而是专注于使用 TensorRT 对原模型推理进行加速。
正确部署后,直接运行示例程序 python inference.py,出现下图所示的任务日志
可以看到,在这几个推理阶段中,最后的 Face Renderer 耗时最严重,因此我们这里主要来对这个模型进行优化。
当前测试的系统环境为:
System: Centos 7
GPU: V1...
点我阅读更多...
CUDA 编程入门(7):并行 Reduction 及其 kernel 优化技术
本文受 Mark Harris 的 Reduction PPT[0] 启发编写
CUDA 编程涉及到许多概念,包括 GPU 硬件相关的,CUDA 编程模型相关的,以及并行计算理论相关的,如果能够对这些概念有充分的理解并加以应用,那么就有可能写出更高性能的 CUDA 程序。本文以经典的 Reduction 算子——数组求和——为例,逐步介绍一些常见的 kernel 优化技术,并展示这些技术是如何提升 CUDA 程序的性能的。
Roofline 模型分析
在正式编写代码实现某个算法之前,我们可以先分析该算法在指定硬件上的 Roofline 模型,从而对该算法的极限性能有个大致的预期。对于单精度数组求和这个任务来说,假设其元素数量等于 n,则运算量为 n-1 次加法,内存读取比...
点我阅读更多...
TensorRT 使用指南(3):自定义算子插件
自定义插件开发基本流程
TensorRT 本身只是一个推理优化框架,它需要从其他训练框架的模型中解析出网络结构,因此常常会遇到一些 TensorRT 不支持的算子,这时我们就需要用插件扩展功能来自己实现这些算子。
简单来说,开发一个 TensorRT 自定义算子插件的流程是:
首先明确要开发的算子,最好是先用 CUDA 实现;
开发插件类,实现 IPluginV2DynamicExt 接口,在这里调用前面实现的算子;
开发插件 Creator 类,实现 IPluginCreator 接口,用于创建插件实例,然后注册该 Creator 类;
编译插件项目,生成动态链接库;
在构造 engine 之前,首先加载上一步编译出来的插件动态链接库,在构造 engine...
点我阅读更多...
分析 GPT 模型自回归生成过程中的 KV Cache 优化技术
类 GPT 模型在自回归生成过程中,每一次推理只生成一个 token,然后将生成的 token 拼接到输入序列,再进行下一次推理,直到生成 eos 或者达到最大长度。在这个过程中,每次推理的计算量都会增加,假设每个 token 的计算量为 1 个单位,则在 context 的长度为 $L$,生成序列长度为 $M$ 的情况下,总的计算量为 $(M + 1) L + \frac{M (M + 1)} 2$ 个单位。
KV Cache 的使用者认为上述过程的大部分运算是可以避免的,比如每个 token 输入模型之后,内部的 key 和 value 可以缓存起来,后续就不必再计算了。也就是说除了第一次推理是将 整个prompt 输入模型,后续每次推理都是将新生成的 token 作为输入,这样...
点我阅读更多...