LMDeploy 量化部署 LLM-VLM 实践
目录
大模型部署的挑战
前向推理计算量大
计算量开销大
访存瓶颈-访存密集任务,严重的访存性能
大模型部署方法
模型剪枝
类比大脑中的神经元大部分都是未开发的,减少一些对应用无关和冗余的组件,比如参数,对于实际的功能影响微乎其微。
知识蒸馏
使用性能较好的模型训练小模型,以达到小模型模仿大模型的目的。
类似于知识迁移,就像教书育人一样吧。
量化
存储使用整数,计算使用浮点数。因为计算速度远大于存储速度,不会降低推理速度
LMDeply
高效推理
量化压缩
服务化部署
实践
配置环境
pip install lmdeploy[all]==0.3.0
studio-conda -t lmdeploy -o pytorch-2.1.2
补充知识:
HuggingFace
HuggingFace是一个高速发展的社区,包括Meta、Google、Microsoft、Amazon在内的超过5000家组织机构在为HuggingFace开源社区贡献代码、数据集和模型。托管在HuggingFace社区的模型通常采用HuggingFace格式存储,简写为HF格式。
TurboMind
TurboMind是LMDeploy团队开发的一款关于LLM推理的高效推理引擎,它的主要功能包括:LLaMa 结构模型的支持,continuous batch 推理模式和可扩展的 KV 缓存管理器。
建立模型软连接
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b /root/
使用transformer加载模型并对话
创建文件并输入下面代码
经过前面的学习对于下面流程也很熟悉了,加载本地模型,并和模型对话
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("/root/internlm2-chat-1_8b", trust_remote_code=True)
# Set `torch_dtype=torch.float16` to load model in float16, otherwise it will be loaded as float32 and cause OOM Error.
model = AutoModelForCausalLM.from_pretrained("/root/internlm2-chat-1_8b", torch_dtype=torch.float16, trust_remote_code=True).cuda()
model = model.eval()
inp = "hello"
print("[INPUT]", inp)
response, history = model.chat(tokenizer, inp, history=[])
print("[OUTPUT]", response)
inp = "please provide three suggestions about time management"
print("[INPUT]", inp)
response, history = model.chat(tokenizer, inp, history=history)
print("[OUTPUT]", response)
这是模型的输出
使用LLMdeply对话(基础作业)
lmdeploy chat /root/internlm2-chat-1_8b
大模型输出
LMDeploy-kv cache
KV8量化是指将逐 Token(Decoding)生成过程中的上下文 K 和 V 中间结果进行 INT8 量化(计算时再反量化),以降低生成过程中的显存占用。
W4A16 量化,将 FP16 的模型权重量化为 INT4,Kernel 计算时,访存量直接降为 FP16 模型的 1/4,大幅降低了访存成本。Weight Only 是指仅量化权重,数值计算依然采用 FP16(需要将 INT4 权重反量化)。
KV Cache是一种缓存技术,通过存储键值对的形式来复用计算结果,以达到提高性能和降低内存消耗的目的。在大规模训练和推理中,KV Cache可以显著减少重复计算量,从而提升模型的推理速度。理想情况下,KV Cache全部存储于显存,以加快访存速度。当显存空间不足时,也可以将KV Cache放在内存,通过缓存管理器控制将当前需要使用的数据放入显存。
–cache-max-entry-count 设置KV Cach的大小
设置最大KV Cache缓存大小
默认kv cache(0.8)与模型对话
lmdeploy chat /root/internlm2-chat-1_8b
显存占用
kv cache 0.5与模型对话
lmdeploy chat /root/internlm2-chat-1_8b --cache-max-entry-count 0.5
显存占用
kv cache 0.01与模型对话
lmdeploy chat /root/internlm2-chat-1_8b --cache-max-entry-count 0.01
显存占用
W4A16量化
安装环境
pip install einops==0.7.0
执行命令
lmdeploy lite auto_awq \
/root/internlm2-chat-1_8b \
--calib-dataset 'ptb' \
--calib-samples 128 \
--calib-seqlen 1024 \
--w-bits 4 \
--w-group-size 128 \
--work-dir /root/internlm2-chat-1_8b-4bit
lite 启动量化功能
auto_awq 自动awq算法
–calib-dataset ‘ptb’ 使用ptb数据集
–calib-samples 128 采样128数据对
–calib-seqlen 1024 上下文权重1024
–w-bits 4 对应量化位数
量化后模型
kv cache 0.01和量化模型对话
lmdeploy chat /root/internlm2-chat-1_8b-4bit --model-format awq --cache-max-entry-count 0.01
显存占用,几乎降低了一半
LMDeploy服务(serve)
大模型系统架构图
模型推理/服务。主要提供模型本身的推理,一般来说可以和具体业务解耦,专注模型推理本身性能的优化。可以以模块、API等多种方式提供。
API Server。中间协议层,把后端推理/服务通过HTTP,gRPC或其他形式的接口,供前端调用。
Client。可以理解为前端,与用户交互的地方。通过通过网页端/命令行去调用API接口,获取模型推理/服务。
启动服务器
lmdeploy serve api_server \
/root/internlm2-chat-1_8b \
--model-format hf \
--quant-policy 0 \
--server-name 0.0.0.0 \
--server-port 23333 \
--tp 1
api_server 启动api_server服务器
–model-format hf 模型格式 huggingface格式
–quant-policy 0 不适用量化
–server-name 0.0.0.0 服务地址
–server-port 23333。端口号
–tp 1 gpu数量
通过命令行方式连接
lmdeploy serve api_client http://localhost:23333
聊天
现在使用的交互流程
网页客户端连接API服务器
启动服务器
lmdeploy serve gradio http://localhost:23333 \
--server-name 0.0.0.0 \
--server-port 6006
部署成功并对话
当前的系统架构
python代码集成
from lmdeploy import pipeline
pipe = pipeline('/root/internlm2-chat-1_8b')
response = pipe(['Hi, pls intro yourself', '上海是'])
print(response)
简单简单明了,通过pipline和模型对话
向TurboMind后端传递参数
from lmdeploy import pipeline, TurbomindEngineConfig
# 调低 k/v cache内存占比调整为总显存的 20%
backend_config = TurbomindEngineConfig(cache_max_entry_count=0.2)
pipe = pipeline('/root/internlm2-chat-1_8b',
backend_config=backend_config)
response = pipe(['Hi, pls intro yourself', '上海是'])
print(response)
把参数封装在TurbomindEngineConfig对象中
执行后
运行llava
安装依赖库
pip install git+https://github.com/haotian-liu/LLaVA.git@4e2277a060da264c4f21b364c867cc622c945874
加载模型,加载图片,模型返回
代码
import gradio as gr
from lmdeploy import pipeline, TurbomindEngineConfig
backend_config = TurbomindEngineConfig(session_len=8192) # 图片分辨率较高时请调高session_len
# pipe = pipeline('liuhaotian/llava-v1.6-vicuna-7b', backend_config=backend_config) 非开发机运行此命令
pipe = pipeline('/share/new_models/liuhaotian/llava-v1.6-vicuna-7b', backend_config=backend_config)
def model(image, text):
if image is None:
return [(text, "请上传一张图片。")]
else:
response = pipe((text, image)).text
return [(text, response)]
demo = gr.Interface(fn=model, inputs=[gr.Image(type="pil"), gr.Textbox()], outputs=gr.Chatbot())
demo.launch()
进阶作业1
设置KV Cache最大占用比例为0.4,开启W4A16量化,以命令行方式与模型对话。
命令
lmdeploy chat /root/internlm2-chat-1_8b-4bit --model-format awq --cache-max-entry-count 0.4
模型对话
进阶作业2
以API Server方式启动 lmdeploy,开启 W4A16量化,调整KV Cache的占用比例为0.4,分别使用命令行客户端与Gradio网页客户端与模型对话。
查看lmdeploy server参数
lmdeploy serve api_server -h
–cahe-max-entry-count 0.4 设置kv cache
–model-format. 看注释,如果要执行量化模型 ,需要 修改 hf 为 awq
–quant-policy 是否使用int8 我们是int4量化,保持默认值0,但是我修改成1也能启动成功。
lmdeploy serve api_server \
/root/internlm2-chat-1_8b-4bit \
--model-format awq \
--quant-policy 0 \
--server-name 0.0.0.0 \
--server-port 23333 \
--cache-max-entry-count 0.4 \
--tp 1
命令行对话
```bash
lmdeploy serve api_client http://localhost:23333
完成对话
启动web服务器
```bash
lmdeploy serve gradio http://localhost:23333 \
--server-name 0.0.0.0 \
--server-port 6006
完成对话
进阶作业3
使用W4A16量化,调整KV Cache的占用比例为0.4,使用Python代码集成的方式运行internlm2-chat-1.8b模型。(优秀学员必做)
from lmdeploy import pipeline, TurbomindEngineConfig
backend_config = TurbomindEngineConfig(cache_max_entry_count=0.4, model_format = 'awq')
pipe = pipeline('/root/internlm2-chat-1_8b-4bit',
backend_config=backend_config)
response = pipe(['Hi, pls intro yourself', '上海是'])
print(response)
模型位置改成量化后的模型root/internlm2-chat-1_8b-4bit
model_format参数为awq
其他参数采用默认值即可
下图是TurbomindEngineConfig类的参数
模型返回
进阶作业4
使用 LMDeploy 运行视觉多模态大模型 llava gradio demo (优秀学员必做)
加载模型,上传图片,页面展示模型返回值
import gradio as gr
from lmdeploy import pipeline, TurbomindEngineConfig
backend_config = TurbomindEngineConfig(session_len=8192) # 图片分辨率较高时请调高session_len
# pipe = pipeline('liuhaotian/llava-v1.6-vicuna-7b', backend_config=backend_config) 非开发机运行此命令
pipe = pipeline('/share/new_models/liuhaotian/llava-v1.6-vicuna-7b', backend_config=backend_config)
def model(image, text):
if image is None:
return [(text, "请上传一张图片。")]
else:
response = pipe((text, image)).text
return [(text, response)]
demo = gr.Interface(fn=model, inputs=[gr.Image(type="pil"), gr.Textbox()], outputs=gr.Chatbot())
demo.launch()
web浏览