第5节LMDeploy 大模型量化部署实践:笔记

理论部分

大模型部署背景

我们先来介绍一下大模型的特点:
首先就是参数量大,对于7B的模型,就需要14G以上的内存,并且由于是采用自回归的方式,所以这就需要去缓存之前的信息,这就会进一步增加消耗。而部署的定义就是将训练好的模型放在特定的环境(cpu,gpu,tpu,npu)接收输入,产生输出。这就要对模型进行优化,如模型压缩和硬化加速。

从上面可以得出如何在低存储的设备上部署?如何提高token推理的速度?如何解决动态token的问题?如何提供系统吞吐量?对此现在有很多成熟的技术:低比特量化,模型并行等。在这里插入图片描述

LMDeploy

从下图中可以看到主要有3个部分:轻量化:如4bit量化(相对于float16可以缩小到1/4),推理引擎:这部分的话底层都是由c++写的,感觉c++确实要去学习的呀,我这方面基础很差,最后就是服务端。

在这里插入图片描述

下图是展示推理性能,可以看到动态效果提高很明显

在这里插入图片描述

量化

量化除了我们知道的可以减少模式的大小,但还有一个很重要的功能,就是可以提高token推理的速度。首先我们要先了解一个概念就是推理分为两种:一个是计算密集型,一种是访存密集型。对于这两种任务前者是在推理时把大部分时间用在计算上面,这种可以选择更加快速的硬件来加速,对于访问密集型是把大多数时间都用在访问存储上面,因为大模型是only-decoder结构,所以就属于这种。所以进行量化可谓一举多得:首先多于模型量化之后,访存的成本更低,这样推理速度会更快,此外也会降低显存消耗。

在这里插入图片描述
那么我们是怎么做到量化的呢?使用的是AWQ算法(这个算法课程里没有讲,我看了一下没咋懂,先往下学吧),量化到4bit,之后在推理的时候,将权重反量化FP16计算。

在这里插入图片描述

TurboMind

下面介绍一个推理引擎–TurboMind,下图是概述

在这里插入图片描述
持续批处理:这个感觉跟操作系统的流水线命令很像呀,可以更加提高吞吐量,工作流程:对于一个请求队列,先将请求放到batch stores中,先到先处理,处理完由后面的补上,这样就可以不用等待,一直推理。
在这里插入图片描述
有状态的推理:这里有点没听明白在这里插入图片描述
分块状态调整,根据是否用到了进行状态迁移从而减少显存的占用。
在这里插入图片描述

实践部分

环境

# 创建虚拟环境
/root/share/install_conda_env_internlm_base.sh lmdeploy

# 激活环境
conda activate lmdeploy

在这里插入图片描述

安装lmdeploy

默认安装的是 runtime 依赖包,但是我们这里还需要部署和量化,所以,这里选择 [all]

# 解决 ModuleNotFoundError: No module named 'packaging' 问题
pip install packaging
# 使用 flash_attn 的预编译包解决安装过慢问题
pip install /root/share/wheels/flash_attn-2.4.2+cu118torch2.0cxx11abiTRUE-cp310-cp310-linux_x86_64.whl

pip install 'lmdeploy[all]==v0.1.0'

在这里插入图片描述

服务部署

架构上把整个服务流程分成下面几个模块。

模型推理/服务。主要提供模型本身的推理,一般来说可以和具体业务解耦,专注模型推理本身性能的优化。可以以模块、API等多种方式提供。
Client。可以理解为前端,与用户交互的地方。
API Server。一般作为前端的后端,提供与产品和服务相关的数据和功能支持。
在这里插入图片描述

模型转换

我们这里会使用TurboMind来推理模型,TurboMind 是一款关于 LLM 推理的高效推理引擎,基于英伟达的 FasterTransformer 研发而成。它的主要功能包括:LLaMa 结构模型的支持,persistent batch 推理模式和可扩展的 KV 缓存管理器。

这里我们要先先将模型转化为 TurboMind 的格式。有两种方式在线转换和本地转换,我们这里因为网络的原因,选择后者:

lmdeploy convert internlm-chat-7b  /root/share/temp/model_repos/internlm-chat-7b/

在这里插入图片描述

TurboMind 推理+命令行本地对话

因为这里是使用本地,就省略了api的部分。流程呢就是我们先将一个大模型在我们的自定义数据集上进行微调,之后进行合并,将这个得到的模型转换TurboMind 格式,这样就可以进行加速推理了。

lmdeploy chat turbomind ./workspace

在这里插入图片描述

TurboMind推理+API服务

在上面的部分我们尝试了直接用命令行启动 Client,接下来我们尝试如何运用 lmdepoy 进行服务化。

这里有个坑,不能直接复制教程里面的命令,要像我下面改一下

# ApiServer+Turbomind   api_server => AsyncEngine => TurboMind
lmdeploy serve api_server ./workspace --server_name 0.0.0.0 --server_port 23333 --instance_num 64 --tp 1

首先我们启动服务,上面的参数中 server_name 和 server_port 分别表示服务地址和端口,tp 参数我们之前已经提到过了,表示 Tensor 并行。还剩下一个 instance_num 参数,表示实例数,可以理解成 Batch 的大小。
在这里插入图片描述
这时我们开启客户端调用

lmdeploy serve api_client http://localhost:23333

在这里插入图片描述
我们尝试一下在这里插入图片描述
但之后我们点不开这个链接查看,这时要先在本地设置一下端口在这里插入图片描述
之后查看http://localhost:23333/可以看到下面的页面

最佳实践

我想对外提供类似 OpenAI 那样的 HTTP 接口服务。推荐使用 TurboMind推理 + API 服务

我想做一个演示 Demo,Gradio 无疑是比 Local Chat 更友好的。推荐使用 TurboMind 推理作为后端的Gradio进行演示

我想直接在自己的 Python 项目中使用大模型功能。推荐使用 TurboMind推理 + Python

我想在自己的其他非 Python 项目中使用大模型功能。推荐直接通过 HTTP 接口调用服务。也就是用本列表第一条先启动一个 HTTP API 服务,然后在项目中直接调用接口。

模型配置:config.ini,使用这个文件进行配置:其实绝大多数我们是不能更改的,比如模型配置和数据这些。我们可以决定的有三个开关。

KV int8 开关:对应参数为 quant_policy,默认值为 0,表示不使用 KV Cache,如果需要开启,则将该参数设置为 4。
KV Cache 是对序列生成过程中的 K 和 V 进行量化,用以节省显存。我们下一部分会介绍具体的量化过程。
当显存不足,或序列比较长时,建议打开此开关。

外推能力开关:对应参数为 rope_scaling_factor,默认值为 0.0,表示不具备外推能力,设置为 1.0,可以开启 RoPE 的 Dynamic NTK 功能,支持长文本推理。另外,use_logn_attn 参数表示 Attention 缩放,默认值为 0,如果要开启,可以将其改为 1。
外推能力是指推理时上下文的长度超过训练时的最大长度时模型生成的能力。如果没有外推能力,当推理时上下文长度超过训练时的最大长度,效果会急剧下降。相反,则下降不那么明显,当然如果超出太多,效果也会下降的厉害。
当推理文本非常长(明显超过了训练时的最大长度)时,建议开启外推能力。

批处理大小:
对应参数为 max_batch_size,默认为 64,也就是我们在 API Server 启动时的 instance_num 参数。
该参数值越大,吞度量越大(同时接受的请求数),但也会占用更多显存。
建议根据请求量和最大的上下文长度,按实际情况调整。

量化

KV Cache 量化

KV Cache 量化是指将逐 Token(Decoding)生成过程中的上下文 K 和 V 中间结果进行 INT8 量化(计算时再反量化),以降低生成过程中的显存占用。

第一步 计算 minmax:主要思路是通过计算给定输入样本在每一层不同位置处计算结果的统计情况。

cp /root/share/temp/datasets/c4/calib_dataloader.py  /root/.conda/envs/lmdeploy/lib/python3.10/site-packages/lmdeploy/lite/utils/

cp -r /root/share/temp/datasets/c4/ /root/.cache/huggingface/datasets/

# 计算 minmax
lmdeploy lite calibrate \
  --model  /root/share/temp/model_repos/internlm-chat-7b/ \
  --calib_dataset "c4" \
  --calib_samples 128 \
  --calib_seqlen 2048 \
  --work_dir ./quant_output

第二步是获取参数

# 通过 minmax 获取量化参数
lmdeploy lite kv_qparams \
  --work_dir ./quant_output  \
  --turbomind_dir workspace/triton_models/weights/ \
  --kv_sym False \
  --num_tp 1

第三步修改weights/config.ini,将quant_policy 改为 4。

W4A16 量化

4bit Weight 量化,将 FP16 的模型权重量化为 INT4,Kernel 计算时,访存量直接降为 FP16 模型的 1/4,大幅降低了访存成本。Weight Only 是指仅量化权重,数值计算依然采用 FP16(需要将 INT4 权重反量化)。

第一步同上。

第二步:

# 量化权重模型
lmdeploy lite auto_awq \
  --model  /root/share/temp/model_repos/internlm-chat-7b/ \
  --w_bits 4 \
  --w_group_size 128 \
  --work_dir ./quant_output 

第三步:

lmdeploy convert  internlm-chat-7b ./quant_output \
    --model-format awq \
    --group-size 128 \
    --dst_path ./workspace_quant

最佳实践

首先我们需要明白一点,服务部署和量化是没有直接关联的,量化的最主要目的是降低显存占用,主要包括两方面的显存:模型参数和中间过程计算结果。前者对应W4A16 量化,后者对应KV Cache 量化。

量化在降低显存的同时,一般还能带来性能的提升,因为更小精度的浮点数要比高精度的浮点数计算效率高,而整型要比浮点数高很多。

  • 33
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值