LMDeploy 量化部署实践
- 任务一:
- 创建虚拟环境
- 创建文件夹LMDEPLOY用于存放课程相关的文件
- 创建模型软连接
- LMDeploy验证启动模型文件
- LMDeploy API部署InternLM2.5-1.8b
- 以命令行形式连接API服务器
- 以Gradio网页形式连接API服务器
- LMDeploy KV量化
- W4A16 模型量化和部署
- W4A16 量化+ KV cache+KV cache 量化
- API开发
- 任务2:Function call
任务一:
- 使用结合W4A16量化与kv cache量化的internlm2_5-1_8b-chat模型封装本地API并与大模型进行一次对话,作业截图需包括显存占用情况与大模型回复
创建虚拟环境
conda create -n lmdeploy python=3.10 -y
conda activate lmdeploy
conda install pytorch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 pytorch-cuda=12.1 -c pytorch -c nvidia -y
pip install timm==1.0.8 openai==1.40.3 lmdeploy[all]==0.5.3
创建文件夹LMDEPLOY用于存放课程相关的文件
mkdir LMDEPLOY
cd LMDEPLOY
创建模型软连接
mkdir models
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-7b-chat /root/LMDEPLOY/models
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat /root/LMDEPLOY/models
ln -s /root/share/new_models/OpenGVLab/InternVL2-26B /root/LMDEPLOY/models
LMDeploy验证启动模型文件
lmdeploy chat /root/LMDEPLOY/models/internlm2_5-1_8b-chat
简单问一下mindsearch是什么
新开一个bash窗口,查看当前gpu使用情况
studio-smi
可以看到模型占用GPU 20G
LMDeploy API部署InternLM2.5-1.8b
启动API服务器
lmdeploy serve api_server \/root/LMDEPLOY/models/internlm2_5-1_8b-chat \--model-format hf \--quant-policy 0 \--server-name 0.0.0.0 \--server-port 23333 \--tp 1
此时的gpu占用20G
打开powershell
运行一下命令
ssh -CNg -L 23333:127.0.0.1:23333 root@ssh.intern-ai.org.cn -p 你的ssh端口号
打开浏览器,访问http://127.0.0.1:23333
看到如下界面即代表部署成功。
以命令行形式连接API服务器
新开一个窗口运行一下命令
conda activate lmdeploy
lmdeploy serve api_client http://localhost:23333
此时便可以在命令行和模型进行对话
以Gradio网页形式连接API服务器
输入以下命令,使用Gradio作为前端,启动网页。
lmdeploy serve gradio http://localhost:23333 \--server-name 0.0.0.0 \--server-port 6006
打开powershell 输入以下命令
ssh -CNg -L 6006:127.0.0.1:6006 root@ssh.intern-ai.org.cn -p 你的ssh端口号
打开浏览器,访问http://127.0.0.1:6006
看到如下界面即代表部署成功。
LMDeploy KV量化
LMDeploy 支持在线 kv cache int4/int8 量化,量化方式为 per-head per-token 的非对称量化。此外,通过 LMDeploy 应用 kv 量化非常简单,只需要设定 quant_policy 和cache-max-entry-count参数。目前,LMDeploy 规定 quant_policy=4 表示 kv int4 量化,quant_policy=8 表示 kv int8 量化。
输入以下指令,启动API服务器。
lmdeploy serve api_server \/root/LMDEPLOY/models/internlm2_5-1_8b-chat \--model-format hf \--quant-policy 4 \--cache-max-entry-count 0.4\--server-name 0.0.0.0 \--server-port 23333 \--tp 1
新开一个窗口查看gpu占用情况,约为12G,对比默认的cache-max-entry-count 0.8 少占用了8G左右
W4A16 模型量化和部署
运行以下命令开始量化模型
lmdeploy lite auto_awq \/root/LMDEPLOY/models/internlm2_5-1_8b-chat \--calib-dataset 'ptb' \--calib-samples 128 \--calib-seqlen 2048 \--w-bits 4 \--w-group-size 128 \--batch-size 1 \--search-scale False \--work-dir /root/LMDEPLOY/models/internlm2_5-1_8b-chat-w4a16-4bit
等待了1个多小时后,量化终于完成
大小和原模型相比小了1半以上
启动看一下显存占用情况
lmdeploy chat /root/LMDEPLOY/models/internlm2_5-1_8b-chat-w4a16-4bit/ --model-format awq
显存占用情况不没有少很多
W4A16 量化+ KV cache+KV cache 量化
两种量化手段一起上
lmdeploy serve api_server \/root/LMDEPLOY/models/internlm2_5-1_8b-chat-w4a16-4bit/ \--model-format awq \--quant-policy 4 \--cache-max-entry-count 0.4\--server-name 0.0.0.0 \--server-port 23333 \--tp 1
显存占用
API开发
启动API服务器
lmdeploy serve api_server \/root/LMDEPLOY/models/internlm2_5-1_8b-chat-w4a16-4bit \--model-format awq \--cache-max-entry-count 0.4 \--quant-policy 4 \--server-name 0.0.0.0 \--server-port 23333 \--tp 1
此时得显存占用是
新建internlm2_5.py。
touch /root/LMDEPLOY/internlm2_5.py
输入以下代码
# 导入openai模块中的OpenAI类,这个类用于与OpenAI API进行交互
from openai import OpenAI# 创建一个OpenAI的客户端实例,需要传入API密钥和API的基础URL
client = OpenAI(api_key='YOUR_API_KEY', # 替换为你的OpenAI API密钥,由于我们使用的本地API,无需密钥,任意填写即可base_url="http://0.0.0.0:23333/v1" # 指定API的基础URL,这里使用了本地地址和端口
)# 调用client.models.list()方法获取所有可用的模型,并选择第一个模型的ID
# models.list()返回一个模型列表,每个模型都有一个id属性
model_name = client.models.list().data[0].id# 使用client.chat.completions.create()方法创建一个聊天补全请求
# 这个方法需要传入多个参数来指定请求的细节
response = client.chat.completions.create(model=model_name, # 指定要使用的模型IDmessages=[ # 定义消息列表,列表中的每个字典代表一个消息{"role": "system", "content": "你是一个友好的小助手,负责解决问题."}, # 系统消息,定义助手的行为{"role": "user", "content": "帮我讲述一个关于狐狸和西瓜的小故事"}, # 用户消息,询问时间管理的建议],temperature=0.8, # 控制生成文本的随机性,值越高生成的文本越随机top_p=0.8 # 控制生成文本的多样性,值越高生成的文本越多样
)# 打印出API的响应结果
print(response.choices[0].message.content)
运行python代码
python /root/LMDEPLOY/internlm2_5.py
此时代表我们成功地使用本地API与大模型进行了一次对话,如果切回第一个终端窗口,会看到如下信息,这代表其成功的完成了一次用户问题GET与输出POST。
任务2:Function call
启动API服务器
友情提示,这个任务要用internlm2_5-7b-chat, 1.8b那个模型不会调用工具,无论是量化前还是量化后
lmdeploy serve api_server \/root/LMDEPLOY/models/internlm2_5-7b-chat \--model-format hf \--quant-policy 0 \--server-name 0.0.0.0 \--server-port 23333 \--tp 1
新建internlm2_5_func.py。
touch /root/LMDEPLOY/internlm2_5_func.py
输入以下代码:
from openai import OpenAIdef add(a: int, b: int):return a + bdef mul(a: int, b: int):return a * btools = [{'type': 'function','function': {'name': 'add','description': 'Compute the sum of two numbers','parameters': {'type': 'object','properties': {'a': {'type': 'int','description': 'A number',},'b': {'type': 'int','description': 'A number',},},'required': ['a', 'b'],},}
}, {'type': 'function','function': {'name': 'mul','description': 'Calculate the product of two numbers','parameters': {'type': 'object','properties': {'a': {'type': 'int','description': 'A number',},'b': {'type': 'int','description': 'A number',},},'required': ['a', 'b'],},}
}]
messages = [{'role': 'user', 'content': 'Compute (3+5)*2'}]client = OpenAI(api_key='YOUR_API_KEY', base_url='http://0.0.0.0:23333/v1')
model_name = client.models.list().data[0].id
response = client.chat.completions.create(model=model_name,messages=messages,temperature=0.8,top_p=0.8,stream=False,tools=tools)
print(response)
func1_name = response.choices[0].message.tool_calls[0].function.name
func1_args = response.choices[0].message.tool_calls[0].function.arguments
func1_out = eval(f'{func1_name}(**{func1_args})')
print(func1_out)messages.append({'role': 'assistant','content': response.choices[0].message.content
})
messages.append({'role': 'environment','content': f'3+5={func1_out}','name': 'plugin'
})
response = client.chat.completions.create(model=model_name,messages=messages,temperature=0.8,top_p=0.8,stream=False,tools=tools)
print(response)
func2_name = response.choices[0].message.tool_calls[0].function.name
func2_args = response.choices[0].message.tool_calls[0].function.arguments
func2_out = eval(f'{func2_name}(**{func2_args})')
print(func2_out)
运行脚本:
python /root/LMDEPLOY/internlm2_5_func.py
我们可以看出InternLM2.5将输入’Compute (3+5)*2’根据提供的function拆分成了"加"和"乘"两步,第一步调用function add实现加,再于第二步调用function mul实现乘,再最终输出结果16.