LMDeploy 大模型量化部署实践
大模型部署背景
模型部署
定义:
1、将训练好的模型在特定的软硬件环境中启动的过程,使模型能够接收输入并返回预测效果
2、为了满足性能和效率的需求,常常需要对模型进行优化,例如模型压缩和硬件加速
产品形态
云端、边缘计算端,移动端等
计算设备
CPU,GPU,NPU,TPU等
大模型特点
内存开销巨大
庞大的参数量。7B模型仅权重就需要14+G的内存
采用自回归生成token,需要缓存Attention 的k/v
带来巨大的内存开销
动态shape
请求数不固定
Token诸葛生成,且数量不定
相对视觉模型,LLM结构简单
Transformers 结构,大部分是decoder-only
大模型部署挑战
设备
如何应对巨大的存储问题?低存储设备(消费级显卡,手机等)如何部署?
推理
如何加速token的生成速度
如何解决动态shape,让推理可以不间断(多个batch中token长度可能不一样,不可能让token短的等token长的完成后才能继续下一个)
如何有效管理和利用内存
服务
如何提升系统整体吞吐量?
对于个体用户,如何降低响应时间?
大模型部署方案
技术点
模型并行:transformer计算和访存优化
低比特量化:Continuous Batch(解决动态shape问题)
Page Attention
方案
huggingface transformers
专门的推理加速框架
LMDeploy 简介
LMDeploy 是LLM在英伟达设备上部署的全流程解决方案。包括模型轻量化、推理和服务。
高效推理引擎
持续批处理技巧
Blocked k/v cache
深度优化的计算kernels
动态分割与融合
完备易用的工具链
量化、推理、服务全流程
无缝对接opencompass评测推理精度
多维度推理速度评测工具
支持交互式推理,不为历史对话买单
推理性能
核心功能
量化
为什么要做量化?
最直观的答案是我爱我的显存,我希望有限的显存能做更多的事
如下图所示,量化后的模型权重缩小,节省显存,并且提高推理速度
两个基本概念
计算密集:推理的绝大部分时间消耗在数值计算上;针对计算密集场景,可以通过使用更快的硬件计算单元来提升计算速度,比如量化为W8A8使用INT8 Tensor Core 来加速计算
访问密集:推理时,绝大部分时间消耗在数据读取上;针对访问密集型场景,一般是通过提高计算访存比来提升性能
LLM是典型的访存密集型任务
常见的LLM模型是Decoder only架构。推理时大部分时间消耗在逐token生成阶段(Decoding 阶段),是典型的访存密集型场景。
Weight Only量化一举多得
- 4bit weight Only量化,将FP16的模型权重量化为int4,访存量直接将为FP16模型的1/4,大幅降低了访存成本,提高Decoding的速度
- 加速的同时还节省了显存,同样的设备能够支持更大的模型以及更长的对话长度
如何做Weight Only量化?
- LMdeploy使用MIT HAN LAB开源的AWQ算法,量化为4bit模型(核心思想是一小部分最重要的参数不量化,这样性能得到最大的保留,同时显存占用也有显著的下降)
- 推理时,先把4bit权重,反量化为FP16(在Kernel内部进行,从Global Memory读取时仍是4bit),依旧使用的是FP16计算
- 相比于社区使用较多的GPTQ算法,AWQ的推理速度更快,量化的时间更短
推理引擎 TurboMind
持续批处理
请求可以及时加入batch中推理
Batch中已经完成推理的请求及时退出
请求队列
推理时请求首先加入到请求队列中
Persistent线程
1、若batch中有空闲槽位,从队列拉取请求,尽量填满空闲槽位。若无,继续对当前batch中的请求进行forward
2、Batch每forward完一次,判断是否有request推理结束。结束的request,发送结果,释放槽位,继续步骤1
有状态的推理
对话token被缓存在推理侧
用户侧请求无需带上历史对话记录
第一个请求U1到达,创建新的序列。推理完成后输入,输出token以及k/v block会保存下来
当后续请求U1,U2到达,命中序列。推理完成后,输入、输出token更新到序列的token数组,新申请的k/v block加入到序列的block数组中
即server端会帮你保存上下文,并且理论上token是无限长的,具体性能要看服务器支持
Blocked k/v cache
Attention 支持不连续的 k/v block(Paged Attention)
Block状态:
Free 未被任何序列占用
Active 被正在推理的序列占用
Cache 被缓存中的序列占用
高性能 cuda kernel
Flash Attention 2
Split-K decoding
高效的w4a16,kv8 反量化kernel
算子融合
推理服务 api server
一行代码调用api
lmdeploy serve api_server InternLM/internlm-chat-7b --model-name internlm-chat-7b --server-port 8080
Swagger地址:http://0.0.0.0:8080
通过swagger ui查看并体验api server的RESTful接口。前3个和openai接口保持一致,后面的是lmdeploy专有api
动手实践环节
安装
创建开发机
这里 /share/conda_envs 目录下的环境是官方未大家准备好的基础环境,因为该目录是共享只读的,而我们后面需要在此基础上安装新的软件包,所以需要复制到我们自己的 conda 环境(该环境下我们是可写的)。
$ conda create -n CONDA_ENV_NAME --clone /share/conda_envs/internlm-base
然后激