Home

Awesome

总述

<div align=center>
名称参考连接
Qwen-7Bhttps://github.com/QwenLM/Qwen-7B
Reporthttps://github.com/QwenLM/Qwen-7B/blob/main/tech_memo.md
</div>

:tada: 1.项目所需环境

<details> <summary>点我查看所需环境</summary>
# 拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/trt-hackathon/trt-hackathon:final_v1
# 启动容器
docker run --gpus all --name trt2023 -it --rm --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 registry.cn-hangzhou.aliyuncs.com/trt-hackathon/trt-hackathon:final_v1
# 如果容器已经存在并停止
docker start trt2023
# 使用docker ps -s查看运行容器,如果正在运行,使用如下命令进入容器操作
docker exec -it trt2023 bash
</details>

:tada: 2.代码结构

<details> <summary>点我查看代码结构</summary>

# model
tensorrt_llm_july-release-v4/tensorrt_llm/models/qwen7b/model.py

# QWenMLP
tensorrt_llm_july-release-v4/tensorrt_llm/layers/mlp.py

# example
./tensorrt_llm_july-release-v1/examples/qwen7b/
├── README.md
├── benchmarks               # benchmark文件
├── build.py                 # trt模型build
├── configuration_qwen.py    # 修改的HF配置文件
├── convert.py               # 
├── hf_qwen_convert.py       # int8 kv cache scale转换文件
├── model                    # Huggingface 模型相关文件
├── profile.py               # Huggingface模型profile文件
├── run.py                   # TRT-LLM模型运行文件
├── smoothquant.py           # int8相关量化文件
├── summarize.py             # Rouge 来对比模型优化前后的精度差距
├── test_qwen.py             # 测试TRT-LLM模型的精度
├── test_qwen_int8_kv_cache.py # 测试TRT-LLM int8 kv cache模型的精度
├── test_qwen_weight_only.py   # 测试TRT-LLM iweight-only int8模型的精度
├── test_rms_norm.py           # 测试rmsnorm plugin的精度
├── test_swiglu.py             # 测试swiglu plugin的精度
└── weight.py                  # HF模型权重转换相关文件

# rmsnorm plugin
tensorrt_llm_july-release-v1/cpp/tensorrt_llm/kernels/rmsnormKernels.cu
tensorrt_llm_july-release-v1/cpp/tensorrt_llm/kernels/rmsnormKernels.h
tensorrt_llm_july-release-v1/cpp/tensorrt_llm/plugins/rmsnormPlugin/rmsnormPlugin.cpp
tensorrt_llm_july-release-v1/cpp/tensorrt_llm/plugins/rmsnormPlugin/rmsnormPlugin.h
# swiglu plugin
tensorrt_llm_july-release-v1/cpp/tensorrt_llm/kernels/swigluKernels.cu
tensorrt_llm_july-release-v1/cpp/tensorrt_llm/kernels/swigluKernels.h
tensorrt_llm_july-release-v1/cpp/tensorrt_llm/plugins/swigluPlugin/swigluPlugin.cpp
tensorrt_llm_july-release-v1/cpp/tensorrt_llm/plugins/swigluPlugin/swigluPlugin.h
</details>

:tada: 3.运行方式说明

<details> <summary>点我查看运行方式</summary>

# 官方的docker中TensorRT位于/usr/local/TensorRT-9.0.0.2/
cd /root/workspace/tensorrt_llm_july-release-v1/

# 按照/root/workspace/tensorrt_llm_july-release-v1/README.md中说明进行安装和编译

# 如果需要重新编译所有tensorrt_llm代码
./scripts/build_wheel.py --clean --trt_root /usr/local/TensorRT-9.0.0.2/

# 编译完成之后安装tensorrt_llm
pip3 install ./build/tensorrt_llm-0.1.3-py3-none-any.whl

cd /root/workspace/tensorrt_llm_july-release-v1/examples/qwen7b/

# 按照examples/qwen7b/README.md中的说明运行build.py, run.py, summarize.py等.
</details>

主要开发工作

模型简介

通义千问-7B(Qwen-7B) 是阿里云研发的通义千问大模型系列的70亿参数规模的模型。Qwen-7B是基于Transformer的大语言模型, 在超大规模的预训练数据上进行训练得到。预训练数据类型多样,覆盖广泛,包括大量网络文本、专业书籍、代码等。 Qwen-7B结构与LLaMA相似的架构。使用来自公开的超过 2.2 万亿个tokens的数据和 2048 个上下文长度进行预训练,训练数据覆盖一般和专业领域,在语言方面重点关注英语和中文。 与标准transformer的主要区别如下:

<p align="center"> <img src="doc/performance.png" width="1000"/> <p> <br>

开发工作的难点

我们仿照examples的代码组织形式,完成了模型搭建,并可顺利输出文本(实现weight.py/build.py/run.py),用Nsight对模型进行Profiling,并最终确定了有针对性的优化方案,包括:

针对于上述问题我们通过修改TRT-LLM相关源码,开发了相关的plugin和脚本.

开发与优化过程

nsys profile -o qwen python3 run.py --max_output_len=8 --tokenizer_dir ./model --engine_dir=./trt_engines/qwen/7B/trt_engines/fp16/1-gpu/

在Nsight下发现GatedMLP的耗时情况如下图所示:

<div align=center> <img src="./doc/GatedMLP.jpg"/> </div> <div align=center> <img src="./doc/GatedMLP_time.jpg"/> </div>

其在一个block中的一个GatedMLP的耗时为569.092us,因此我们对GatedMLP进行了优化,把self.fcself.gate两个linear融合为一个linear, 然后使用swiglu激活函数。优化后的耗时为557.795us,较优化前缩短了11.297us,相同位置的QWenMLP结构的Nsight如下:

<div align=center> <img src="./doc/QWenMLP.jpg"/> </div> <div align=center> <img src="./doc/QWenMLP_time.jpg"/> </div>

此外还实现了Swiglu Plugin,但是速度比TensorRT中的原生算法融合慢很多,因此弃用之。

<div align=center> <img src="./doc/RMSNorm.jpg"/> </div> <div align=center> <img src="./doc/RMSNorm_time.jpg"/> </div>

其在一个QWenBlock中的一个RMSNorm的耗时为9.312us,因此我们对RMSNorm进行了优化,实现了Rmsnorm Plugin。优化后的耗时为3.776us,较优化前缩短了5.536us,相同位置的QWenMLP结构的Nsight如下:

<div align=center> <img src="./doc/RMSNorm_plugin.jpg"/> </div> <div align=center> <img src="./doc/RMSNorm_plugin_time.jpg"/> </div>
# 以batch_size=1为例
# Run benchmark using the Qwen 7B TRT-LLM model in FP16.
python ./benchmarks/benchmark.py \
    -m qwen \
    --mode plugin \
    --batch_size "1" \
    --input_output_len "10,512" \
    --engine_dir ./trt_engines/qwen/7B/trt_engines/fp16/1-gpu/
    
# Run benchmark using the Qwen 7B TRT-LLM model quantized to INT8.
python ./benchmarks/benchmark.py \
    -m qwen \
    --mode plugin \
    --batch_size "1" \
    --input_output_len "10,512" \
    --use_weight_only \
    --engine_dir ./trt_engines/qwen/7B/trt_engines/weight_only/1-gpu/
batch_sizeFP16 memory(GB)int8 memory(GB)diff(GB)
116.4310.39-6.04
batch_sizeFP16 memory(GB)int8 kv cache(GB)diff(GB)
116.4316.27-0.16

精度与加速结果

# Run summarization using the Qwen 7B HF model in FP16.
python summarize.py --test_hf \
                    --batch_size 1 \
                    --hf_model_location ./model \
                    --data_type fp16 \
                    --check_accuracy \
                    --tensorrt_llm_rouge1_threshold=14 \
                    --engine_dir ./trt_engines/qwen/7B/trt_engines/fp16/1-gpu/
                    
# Run summarization using the Qwen 7B TRT-LLM model in FP16.
python summarize.py --test_trt_llm \
                    --batch_size 1 \
                    --hf_model_location ./model \
                    --data_type fp16 \
                    --check_accuracy \
                    --tensorrt_llm_rouge1_threshold=14 \
                    --engine_dir ./trt_engines/qwen/7B/trt_engines/fp16/1-gpu/

# Run summarization using the Qwen 7B TRT-LLM model weight quantized to INT8.
python summarize.py --test_trt_llm \
                    --batch_size 1 \
                    --hf_model_location ./model \
                    --data_type fp16 \
                    --check_accuracy \
                    --tensorrt_llm_rouge1_threshold=14 \
                    --engine_dir ./trt_engines/qwen/7B/trt_engines/weight_only/1-gpu/
batch_sizeHuggingfaceFP16int8
144.631.321.7
batch_sizeHuggingfaceFP16int8
11.01.422.06
<div align=center> <img src="./doc/summarize_hf.jpg"/> </div> <div align=center> <img src="./doc/summarize_trt_fp16.jpg"/> </div> <div align=center> <img src="./doc/summarize_trt_int8.jpg"/> </div>

关于精度测试的验证仿照tests中的代码,采取的方式是绝对误差和相对误差的均值,中位数和最大值。运行examples/qwen7b/test_qwen.py和examples/qwen7b/test_qwen_weight_only.py程序可以得到运行结果

# 评估HF输出和TRT-LLM输出的FP16模型精度是否对齐
python test_qwen.py

# 评估HF输出和TRT-LLM输出的INT8模型精度是否对齐
python test_qwen_weight_only.py

DataTypemax absmedian absmean absmax relmedian relmean rel
fp160.01370.001950.002420.211440.002250.00505
int80.29190.03590.04263.6590.03890.0893
<div align=center> <img src="./doc/fp16_int8_precision.jpg"/> </div>

送分题答案(可选)

Input: Born in north-east France, Soyer trained as a
Output:  chef before moving to London in the late
[09/06/2023-00:46:00] [TRT-LLM] [I] TensorRT-LLM beam 0 result
[09/06/2023-00:46:00] [TRT-LLM] [I]   rouge1 : 21.869322054781037
[09/06/2023-00:46:00] [TRT-LLM] [I]   rouge2 : 6.258925475911645
[09/06/2023-00:46:00] [TRT-LLM] [I]   rougeL : 16.755771650012953
[09/06/2023-00:46:00] [TRT-LLM] [I]   rougeLsum : 18.68034777724496
[09/06/2023-00:46:00] [TRT-LLM] [I] HF beam 0 result
[09/06/2023-00:46:01] [TRT-LLM] [I]   rouge1 : 18.182978950152904
[09/06/2023-00:46:01] [TRT-LLM] [I]   rouge2 : 5.166241888544473
[09/06/2023-00:46:01] [TRT-LLM] [I]   rougeL : 14.851620358520162
[09/06/2023-00:46:01] [TRT-LLM] [I]   rougeLsum : 16.95757748412272

未来工作

基于TensorRT-LLM和Plugin我们已经搭建了Qwen-7B模型并做了一定的优化,由于时间关系并未进行SmoothQuant等量化,真的非常遗憾,未来希望持续进一步的优化,未来工作: