3. TensorRT-LLM源码获取与结构分析:Git仓库克隆、核心模块解读、依赖库梳理
好,咱们进入正题。这一章,我们来聊聊怎么拿到TensorRT-LLM的源码,并且把它拆开看看里面到底长什么样。说实话,我第一次接触这个项目的时候,也被它的目录结构吓了一跳——东西太多了。但别怕,咱们一步步来。
3.1 源码获取:Git仓库克隆与分支选择
获取源码很简单,就一条命令:
git clone https://github.com/NVIDIA/TensorRT-LLM.git
cd TensorRT-LLM
但这里有个坑,我一开始就踩过。你直接clone下来的是main分支,这个分支可能包含最新的实验性代码,不一定稳定。我个人习惯是切换到发布版本的分支,比如:
git checkout v0.7.1
为什么这么做?因为嵌入式设备上,我们追求的是稳定。我曾经在开发板上用main分支编译,结果遇到一个刚引入的bug,排查了两天才发现是代码版本的问题。所以,我建议你选一个经过验证的release版本。
3.2 核心模块解读:Builder、Runtime、Plugin
源码拿到手了,咱们看看它的目录结构。核心模块就三个:Builder、Runtime、Plugin。说白了,它们分别负责“怎么建”、“怎么跑”、“怎么扩展”。
3.2.1 Builder:模型构建器
Builder在 cpp/tensorrt_llm/builder 目录下。它的任务是把训练好的模型(比如PyTorch的权重)转换成TensorRT能识别的引擎文件。
我举个例子,你有一个LLaMA模型,想部署到嵌入式设备上。Builder会做这几件事:
- 权重转换:把FP32的权重量化成FP16或INT8
- 图优化:合并算子、消除冗余计算
- 内存规划:为每个tensor分配固定的内存地址
嗯,这里要注意,Builder的输出是一个 .engine 文件。这个文件是平台相关的,你在x86上编译的引擎,不能直接拿到ARM上跑。我刚开始做移植时就犯过这个错,折腾了半天才发现是引擎不兼容。
3.2.2 Runtime:运行时引擎
Runtime在 cpp/tensorrt_llm/runtime 目录下。它的职责很简单:加载Builder生成的引擎文件,然后执行推理。
核心接口就几个:
// 加载引擎
auto runtime = std::make_unique<Runtime>(enginePath);
// 准备输入输出
runtime->setInput("input_ids", inputTensor);
runtime->setOutput("logits", outputTensor);
// 执行推理
runtime->execute();
你看,代码量很少。但实际项目中,我遇到过一个问题:Runtime在嵌入式设备上启动时,内存分配可能会失败。为什么?因为设备的内存碎片化严重。我的解决办法是,在初始化时预先分配好所有tensor的内存,避免动态分配。
3.2.3 Plugin:自定义算子插件
Plugin在 cpp/tensorrt_llm/plugins 目录下。TensorRT-LLM里有很多自定义算子,比如FlashAttention、GQA(Grouped Query Attention)等。这些算子不是TensorRT原生的,而是通过Plugin机制注册进去的。
举个例子,FlashAttention插件:
// 注册插件
REGISTER_TENSORRT_PLUGIN(FlashAttentionPluginCreator);
// 在Builder中使用
auto plugin = make_nv_plugin("FlashAttention", ...);
network->addPluginV2(inputs, plugin);
我个人觉得,Plugin是TensorRT-LLM最灵活的部分。你想优化某个算子?自己写一个Plugin就行。我曾经为了在嵌入式设备上加速LayerNorm,写了一个自定义Plugin,推理速度提升了30%。
3.3 依赖库梳理:一个都不能少
TensorRT-LLM的依赖库不少,我列个表给你看:
| 依赖库 | 版本要求 | 作用 | 嵌入式注意事项 |
|---|---|---|---|
| TensorRT | ≥ 8.6 | 核心推理引擎 | 需下载ARM版本 |
| CUDA | ≥ 11.8 | GPU加速 | 嵌入式设备需Jetson系列 |
| cuDNN | ≥ 8.9 | 深度学习原语 | 与CUDA版本匹配 |
| NCCL | ≥ 2.15 | 多卡通信 | 单卡设备可忽略 |
| Python | ≥ 3.8 | 模型转换脚本 | 嵌入式设备上可选 |
| PyTorch | ≥ 2.0 | 模型权重导出 | 只在PC端需要 |
这里我想强调一点:嵌入式设备上,你不需要安装所有依赖。比如PyTorch,你只需要在PC上用它导出权重,然后交叉编译生成引擎。设备上只需要TensorRT Runtime和cuDNN就够了。
3.4 源码结构速览:快速定位关键文件
最后,我带你快速过一遍源码的目录结构。你不需要记住所有文件,但要知道关键文件在哪:
cpp/tensorrt_llm/builder/— Builder核心代码cpp/tensorrt_llm/runtime/— Runtime核心代码cpp/tensorrt_llm/plugins/— 所有Plugin实现examples/— 各种模型的示例脚本(很有参考价值)benchmarks/— 性能测试脚本cmake/— CMake构建配置
我个人习惯是,先看 examples/ 目录下的示例。比如你想部署LLaMA,就看 examples/llama/ 里的脚本。这些示例是官方写好的,能帮你快速上手。
嗯,这一章的内容就到这里。源码拿到了,结构也清楚了,下一章我们就可以开始动手编译了。