随着大模型参数规模的不断增长,在有限的算力资源下,提升模型的推理速度逐渐变为一个重要的研究方向。常用的推理加速框架包含lmdeploy、FasterTransformer和vLLM等。
一.lmdeploy推理部署
lmdeploy由上海人工智能实验室开发,推理使用C++/CUDA,对外提供python/gRPC/http接口和WebUI界面,支持tensor parallel分布式推理、支持fp16/weightint4/kv cache int8量化。lmdeploy支持transformer结构(例如LLaMA、LLaMa2、InternLM、Vicuna等),目前支持fp16,int8和int4。
1.fp16推理
安装预编译的Python包,即python3 -m pip install lmdeploy
。把模型转成lmdeploy 推理格式,假设huggingface版LLaMa2模型已下载到/models/llama-2-7b-chat
目录,结果会存到workspace
文件夹,如下所示:
python3 -m lmdeploy.serve.turbomind.deploy llama2 /models/llama-2-7b-chat
复制
在命令行中测试聊天效果,如下所示:
python3 -m lmdeploy.turbomind.chat ./workspace...double enter to end input >>> who are you...Hello! I'm just an AI assistant ...
复制
也可以用gradio启动WebUI来聊天,如下所示:
python3 -m lmdeploy.serve.gradio.app ./workspace
复制
lmdeploy同样支持原始的facebook模型格式、支持70B模型分布式推理,用法查看lmdeploy 官方文档。
2.kv cache int8量化
lmdeploy实现了kv cache int8量化,同样的显存可以服务更多并发用户。首先计算模型参数,结果是pth格式,保存到临时目录minmax,如下所示:
mkdir minmaxpython3 -m lmdeploy.lite.apis.calibrate \ --model /models/llama-2-7b-chat \ # huggingface llama2 模型。也支持 llama/vicuna/internlm/baichuan 等 --calib_dataset 'c4' \ # 校准数据集,支持 c4, ptb, wikitext2, pileval --calib_samples 128 \ # 校准集的样本数,如果显存不够,可以适当调小 --calib_seqlen 2048 \ # 单条的文本长度,如果显存不够,可以适当调小 --work_dir minmax \ # 保存 pth 格式量化统计参数和量化后权重的文件夹
复制
然后用minmax目录里的参数,计算量化参数,保存到fp16转换好的workspace/triton_models/weights
下,如下所示:
python3 -m lmdeploy.lite.apis.kv_qparams \ --work_dir minmax \ # 上一步计算的 minmax 结果 --turbomind_dir ./workspace/triton_models/weights \ # 结果保存目录 --kv_sym False \ # 用非对称量化 --num_tp 1 # tensor parallel GPU 个数
复制
修改推理配置,开启kv cache int8。编辑workspace/triton_models/weights/config.ini
,如下所示:
(1)把use_context_fmha
改为0,表示关闭flashattention
(2)把quant_policy
设为4,表示打开kv cache量化
最终执行测试即可,如下所示:
python3 -m lmdeploy.turbomind.chat ./workspace
复制
点击这里查看kv cache int8量化实现公式、精度和显存测试报告。
3.weight int4量化
lmdeploy基于AWQ 算法实现了weight int4量化,相对fp16版本,速度是3.16倍、显存从16G降低到6.3G。这里有AWQ算法优化好llama2原始模型,直接下载。如下所示:
git clone https://huggingface.co/lmdeploy/llama2-chat-7b-w4
复制
对于自己的模型,可以用auto_awq
工具来优化,如下所示:
# 计算量化参数python3 -m lmdeploy.lite.apis.calibrate \ --model $HF_MODEL \ # huggingface 模型位置 --calib_dataset 'c4' \ # 校准数据集,支持 c4, ptb, wikitext2, pileval --calib_samples 128 \ # 校准集的样本数,如果显存不够,可以适当调小 --calib_seqlen 2048 \ # 单条的文本长度,如果显存不够,可以适当调小 --work_dir $WORK_DIR \ # 保存 Pytorch 格式量化统计参数和量化后权重的文件夹# 量化模型python3 -m lmdeploy.lite.apis.auto_awq \ --model $HF_MODEL \ # huggingface 模型位置 --w_bits 4 \ # 权重量化的 bit 数 --w_group_size 128 \ # 权重量化分组统计尺寸 --work_dir $WORK_DIR \ # 上一条命令保存参数的目录
复制
执行以下命令,即可在终端与模型对话,如下所示:
## 转换模型的layout,存放在默认路径 ./workspace 下python3 -m lmdeploy.serve.turbomind.deploy \ --model-name llama2 \ --model-path ./llama2-chat-7b-w4 \ --model-format awq \ --group-size 128## 推理python3 -m lmdeploy.turbomind.chat ./workspace
复制
点击这里查看weight int4量化的显存和速度测试结果。额外说明,weight int4和kv cache int8二者并不冲突、可以同时打开,节约更多显存。
二.FasterTransformer推理部署
FasterTransformer由NVIDIA开发,采用C++/CUDA编写,支持分布式推理,transformer编码器和解码器均可进行加速。通过FasterTransformer和Triton加速LLama2模型推理,目前支持FP16或者Int8推理,Int4目前还不支持。
1.镜像构建
准备环境变量,如下所示:
export BUILD_DICTIONARY="/data/build"export TRITON_VERSION=23.04
复制
(1)构建镜像
cd $BUILD_DICTIONARYgit clone https://github.com/Rayrtfr/fastertransformer_backend.git cd $BUILD_DICTIONARY/fastertransformer_backendexport TRITON_VERSION=23.04docker build --build-arg TRITON_VERSION=${TRITON_VERSION} -t triton_ft_backend:${TRITON_VERSION}-v-1 -f docker/Dockerfile-1 .docker build --build-arg TRITON_VERSION=${TRITON_VERSION} -t triton_ft_backend:${TRITON_VERSION} -f docker/Dockerfile-2 .docker build --build-arg TRITON_VERSION=${TRITON_VERSION} -t triton_ft_backend:${TRITON_VERSION}-final -f docker/Dockerfile-3 .
复制
TRITON_VERSION=23.04这个镜像需的GPU的驱动版本是Driver Version: 535.54.03,如果GPU的驱动不是这个版本,需要https://docs.nvidia.com/deeplearning/triton-inference-server/release-notes/rel-22-12.html#rel-22-12找到cuda driver对应版本的triton-inference-server。
(2)启动容器
# 启动容器export TRITON_VERSION=23.04# 注意需要 BUILD_DICTIONARY 挂载到容器里面docker run -idt --gpus=all --net=host --shm-size=4G --name triton_ft_backend_pure \ -v $BUILD_DICTIONARY:$BUILD_DICTIONARY \ -p18888:8888 -p18000:8000 -p18001:8001 -p18002:8002 triton_ft_backend:${TRITON_VERSION}-final bash
复制
2.容器内操作
下面介绍一下Llama2-Chinese-13b-Chat模型的权重转换成FasterTransformer格式。Llama2-Chinese-7b-Chat也是类似的方式。
(1)转换权重,权重转换成FasterTransformer格式
cd $BUILD_DICTIONARYgit clone https://github.com/Rayrtfr/FasterTransformer.gitcd $BUILD_DICTIONARY/FasterTransformermkdir models && sudo chmod -R 777 ./*python3 ./examples/cpp/llama/huggingface_llama_convert.py \-saved_dir=./models/llama \-in_file=/path/FlagAlpha/Llama2-Chinese-13b-Chat \-infer_gpu_num=1 \-weight_data_type=fp16 \-model_name=llama
复制
(2)修改模型配置
编辑config.pbtxt文件,如下所示:
mkdir $BUILD_DICTIONARY/triton-model-store/cd $BUILD_DICTIONARY/triton-model-store/cp -r $BUILD_DICTIONARY/fastertransformer_backend/all_models/llama $BUILD_DICTIONARY/triton-model-store/# 修改 triton-model-store/llama/fastertransformer/config.pbtxtparameters { key: "tensor_para_size" value: { string_value: "1" }}## 修改 model_checkpoint_path 为上面转换之后的路径parameters { key: "model_checkpoint_path" value: { string_value: "/ft_workspace/FasterTransformer/models/llama/1-gpu/" }}## 模型使用int8推理需要加一下面的配置parameters { key: "int8_mode" value: { string_value: "1" } }
复制
修改model.py文件,如下所示:
# 修改这两个文件triton-model-store/llama/preprocess/1/model.pytriton-model-store/llama/postprocess/1/model.py# 检查 这个路径为tokenier对应的路径self.tokenizer = LlamaTokenizer.from_pretrained("/path/FlagAlpha/Llama2-Chinese-13b-Chat")
复制
(3)编译FasterTransformer Library
同一类型的模型,编译一次就行了。编译之前检查FasterTransformer/examples/cpp/llama/llama_config.ini,如下所示:
# 单卡推理这里是1,多卡可以改成卡的数目tensor_para_size=1model_dir=/mnt/data/wuyongyu/train/FasterTransformer/models/llama/1-gpu/
复制
编译FasterTransformer,如下所示:
cd $BUILD_DICTIONARY/FasterTransformermkdir build && cd buildgit submodule init && git submodule updatepip3 install fire jax jaxlib transformerscmake -DSM=86 -DCMAKE_BUILD_TYPE=Release -DBUILD_PYT=ON -DBUILD_MULTI_GPU=ON -D PYTHON_PATH=/usr/bin/python3 ..make -j12make install
复制
3.启动triton server
同样在上面的容器内操作,如下所示:
CUDA_VISIBLE_DEVICES=0 /opt/tritonserver/bin/tritonserver --model-repository=$BUILD_DICTIONARY/triton-model-store/llama/
复制
输出如下所示:
I0717 17:17:14.670037 70681 grpc_server.cc:2450] Started GRPCInferenceService at 0.0.0.0:8001I0717 17:17:14.670495 70681 http_server.cc:3555] Started HTTPService at 0.0.0.0:8000I0717 17:17:14.713000 70681 http_server.cc:185] Started Metrics Service at 0.0.0.0:8002
复制
启动client测试
python3 $BUILD_DICTIONARY/fastertransformer_backend/inference_example/llama/llama_grpc_stream_client.py
复制
三.vLLM推理部署
vllm同样是GPU推理的方案,它由加州大学伯克利分校开发,核心技术是PageAttention,吞吐量比HuggingFace Transformers高出24倍。相较与FasterTrainsformer,vLLM更加的简单易用,不需要额外进行模型的转换,支持fp16推理。特点:快速的推理速度,高效的kv cache,连续的batch请求推理,优化cuda算子,支持分布式推理。
1.安装vllm
vllm安装命令,如下所示:
git clone https://github.com/vllm-project/vllmcd vllm && python setup.py install
复制
2.启动测试server
下载13B模型或者7B模型到特定目录。
(1)单卡推理
编辑single_gpus_api_server.sh里面model为上面的7B或者13B模型的下载路径。启动测试server,如下所示:
# multi_gpus_api_server.sh 里面的CUDA_VISIBLE_DEVICES指定了要使用的GPU卡bash single_gpus_api_server.sh
复制
(2)多卡推理
13B模型,70B模型推荐多卡推理。编辑multi_gpus_api_server.sh里面model为上面的13B模型的下载路径。启动测试server,如下所示:
# multi_gpus_api_server.sh 里面的CUDA_VISIBLE_DEVICES指定了要使用的GPU卡# tensor-parallel-size 指定了卡的个数bash multi_gpus_api_server.sh
复制
3.启动client测试
python client_test.py
复制
参考文献:
[1]https://github.com/FlagAlpha/Llama2-Chinese/tree/main/inference-speed/GPU/lmdeploy_example
[2]https://github.com/FlagAlpha/Llama2-Chinese/tree/main/inference-speed/GPU/FasterTransformer_example
[3]https://github.com/FlagAlpha/Llama2-Chinese/blob/main/inference-speed/GPU/vllm_example/README.md