1.大模型部署背景
定义:在软件工程中,部署通常是指将开发完毕的软件投入使用的过程。
在人工智能领域,模型部署是实现深度学习算法落地应用的关键步骤。简单来 说,模型部署就是将训练好的深度学习模型在特定环境中运行的过程。
大模型部署面临的挑战
- 计算量巨大:前向推理时需要进行大量计算,现在大模型推理计算量达到千万亿量级。
- 内存开销巨大:以FP16为例,加载20B模型参数就需要40G+的显存,而目前NVIDIA RTX 4060消费级显卡为例,单卡显存仅8GB,A100单卡显存仅为80GB。
- 访存瓶颈:大模型推理是“访存密集”型任务。目前硬件计算速度“远快于显存带宽”,存在严重的访存性能瓶颈。
- 动态请求:请求量不确定,请求时间不确定,Token逐个生成和数量不确定。
2.大模型部署方法
(1)模型剪枝(Pruning)
剪枝指移除模型中不必要或多余的组件,比如参数,以使模型更加高效。通过对模型中贡献有限的冗余参数进行枝,在保证性能最低下降的同时,可以减小存储需求、提高计算效率。
具体有以下方法:
- 非结构化剪枝(SparseGPT,LoRAPrune,Wanda)指移除个别参数,而不考虑整体网络结构。这种方法通过将低于國值的参数置零的方式对个别权重或神经元进行处理。
- 结构化剪枝(LLM-Pruner)根据预定义规则移除连接或分层结构,同时保持整体网络结构,这种方法一次性地针对整组权重,优势在于降低模型复杂性和内存使用,同时保持整体的LLM结构完整。
(2)知识蒸馏(Knowledge Distillation,KD)
知识蒸馏是一种典型的模型压缩方法,核心思想是通过引导轻量化的学生模型“模仿”性能更好、结构更复杂的教师模型,在不改变学生模型结构的情况下提高其性能。
方法包括上下文学习、思维链和指令跟随。
(3)量化(Quantization)
量化技术将传统的表示方法中浮点数转换为整数或其他离散形式,以减轻深度学习模型的存储和计算负担。
方法包括:
- 量化感知训练
- 量化感知微调
- 训练后量化
3.LMDeploy简介
简介
LMDeploy 由 MMDeploy 和 MMRazor 团队联合开发是涵盖了 LLM 任务的全套轻量化、部署和服务解决方案。核心功能包括高效推理、可靠量化、便捷服务和有状态推理。
高效的推理:LMDeploy开发了Continuous Batch,Blocked K/V Cache,动态拆分和融合,张量并行,高效的计算kernel等重要特性。InternLM2推理性能是vLLM的 1.8 倍。
可靠的量化:LMDeploy支持权重量化和k/v量化。4bit模型推理效率是FP16下的2.4倍。量化模型的可靠性已通过OpenCompass评测得到充分验证。
便捷的服务:通过请求分发服务,LMDeploy 支持多模型在多机、多卡上的推理服务。
有状态推理:通过缓存多轮对话过程中Attention的k/v,记住对话历史,从而避免重复处理历史会话。显著提升长文本多轮对话场景中的效率。
核心功能
性能表现
推理多模态大模型
支持其他第三方大模型
4.动手实践环节
以下内容是在InternStudio的开发机上运行的
第一步--创建开发机
填写开发机名称;选择镜像Cuda12.2-conda
;选择10% A100*1
GPU;点击“立即创建”。
第二步--配置环境
InternStudio上提供了快速创建conda环境的方法。打开命令行终端,创建一个名为lmdeploy
的环境:
studio-conda -t lmdeploy -o pytorch-2.1.2
接下来,激活刚刚创建的虚拟环境。
conda activate lmdeploy
安装0.3.0版本的lmdeploy。
pip install lmdeploy[all]==0.3.0
下载模型,本次实战营已经在开发机的共享目录中准备好了常用的预训练模型,可以运行如下命 令查看:
ls /root/share/new_models/Shanghai_AI_Laboratory/
如果你是在InternStudio开发机上,可以按照如下步骤快速下载模型。
首先进入一个你想要存放模型的目录,本教程统一放置在Home目录。执行如下指令:
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b /root/
# cp -r /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b /root/
第三步--与LMDeploy模型对话
以下过程均在lmdeploy环境运行,下面不再赘述。
1.使用Transformer库运行模型
在终端中输入如下指令,新建pipeline_transformer.py
。
touch /root/pipeline_transformer.py
将以下内容复制粘贴进入pipeline_transformer.py,并
按Ctrl+S
键保存。
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)
在lmdeploy环境上运行python代码:
python /root/pipeline_transformer.py
2.使用LMDeploy与模型对话
使用LMDeploy与模型进行对话的通用命令格式为:
lmdeploy chat [HF格式模型路径/TurboMind格式模型路径]
例如,您可以执行如下命令运行下载的1.8B模型:
lmdeploy chat /root/internlm2-chat-1_8b
下面我们就可以与InternLM2-Chat-1.8B大模型对话了。比如输入“请给我讲一个小故事吧”,然后按两下回车键。
ssh -CNg -L 23333:127.0.0.1:23333 root@ssh.intern-ai.org.cn -p 你的ssh端口号
输入“exit”并按两下回车,可以退出对话。
3.LMDeploy服务
在开发机终端通过以下命令启动API服务器,推理internlm2-chat-1_8b
模型:
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
注意,这一步由于Server在远程服务器上,所以本地需要做一下ssh转发才能直接访问。在你本地打开一个cmd窗口,输入命令如下:
ssh -CNg -L 23333:127.0.0.1:23333 root@ssh.intern-ai.org.cn -p 你的ssh端口号
a.命令行客户端连接API服务器
在vscode新建一个终端,并在lmdeploy运行命令行客户端:
lmdeploy serve api_client http://localhost:23333
b.网页客户端连接API服务器
关闭刚刚的VSCode终端,但服务器端的终端不要关闭。
在vscode新建一个终端,在lmdeploy环境使用Gradio作为前端,启动网页客户端。
lmdeploy serve gradio http://localhost:23333 \
--server-name 0.0.0.0 \
--server-port 6006
运行命令后,网页客户端启动。在电脑本地新建一个cmd终端,新开一个转发端口:
ssh -CNg -L 6006:127.0.0.1:6006 root@ssh.intern-ai.org.cn -p <你的ssh端口号>
打开浏览器,访问地址http://127.0.0.1:6006
,然后就可以与模型进行对话了!
4.Python代码集成
在开发项目时,有时我们需要将大模型推理集成到Python代码里面。
a.Python代码集成运行1.8B模型
新建Python源代码文件pipeline.py
。
touch /root/pipeline.py
打开pipeline.py
,填入以下内容。
from lmdeploy import pipeline
pipe = pipeline('/root/internlm2-chat-1_8b')
response = pipe(['Hi, pls intro yourself', '上海是'])
print(response)
保存后运行代码文件:
python /root/pipeline.py
b.向TurboMind后端传递参数
我们通过向lmdeploy传递附加参数,实现模型的量化推理,及设置KV Cache最大占用比例。在Python代码中,可以通过创建TurbomindEngineConfig,向lmdeploy传递参数。
新建python文件pipeline_kv.py
。
touch /root/pipeline_kv.py
打开pipeline_kv.py
,填入如下内容:
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)
保存后运行python代码:
python /root/pipeline_kv.py
5.使用LMDeploy运行视觉多模态大模型llava
最新版本的LMDeploy支持了llava多模态模型,下面演示使用pipeline推理llava-v1.6-7b
。注意,运行本pipeline最低需要30%的InternStudio开发机
安装llava依赖库。
pip install git+https://github.com/haotian-liu/LLaVA.git@4e2277a060da264c4f21b364c867cc622c945874
新建一个python文件,比如pipeline_llava.py
touch /root/pipeline_llava.py
打开pipeline_llava.py
,填入内容如下:
from lmdeploy.vl import load_image
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)
image = load_image('https://raw.githubusercontent.com/open-mmlab/mmdeploy/main/tests/data/tiger.jpeg')
response = pipe(('describe this image', image))
print(response)
保存后运行pipeline。
python /root/pipeline_llava.py
我们也可以通过Gradio来运行llava模型。新建python文件gradio_llava.py
。
touch /root/gradio_llava.py
打开文件,填入以下内容:
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()
运行python程序。
python /root/gradio_llava.py
通过ssh转发一下7860端口。
ssh -CNg -L 7860:127.0.0.1:7860 root@ssh.intern-ai.org.cn -p <你的ssh端口>
通过浏览器访问http://127.0.0.1:7860,
然后就可以使用了。
附录
LMDeploy模型量化(lite)
正式介绍 LMDeploy 量化方案前,需要先介绍两个概念:
- 计算密集(compute-bound): 指推理过程中,绝大部分时间消耗在数值计算上;针对计算密集型场景,可以通过使用更快的硬件计算单元来提升计算速度。
- 访存密集(memory-bound): 指推理过程中,绝大部分时间消耗在数据读取上;针对访存密集型场景,一般通过减少访存次数、提高计算访存比或降低访存量来优化。
常见的 LLM 模型由于 Decoder Only 架构的特性,实际推理时大多数的时间都消耗在了逐 Token 生成阶段(Decoding 阶段),是典型的访存密集型场景。
我们可以使用KV8量化和W4A16量化。
KV8量化是指将逐 Token(Decoding)生成过程中的上下文 K 和 V 中间结果进行 INT8 量化(计算时再反量化),以降低生成过程中的显存占用。
W4A16 量化,将 FP16 的模型权重量化为 INT4,Kernel 计算时,访存量直接降为 FP16 模型的 1/4,大幅降低了访存成本。Weight Only 是指仅量化权重,数值计算依然采用 FP16(需要将 INT4 权重反量化)。
1.设置最大KV Cache缓存大小
KV Cache是一种缓存技术,通过存储键值对的形式来复用计算结果,以达到提高性能和降低内存消耗的目的。在大规模训练和推理中,KV Cache可以显著减少重复计算量,从而提升模型的推理速度。理想情况下,KV Cache全部存储于显存,以加快访存速度。当显存空间不足时,也可以将KV Cache放在内存,通过缓存管理器控制将当前需要使用的数据放入显存。
模型在运行时,占用的显存可大致分为三部分:模型参数本身占用的显存、KV Cache占用的显存,以及中间运算结果占用的显存。LMDeploy的KV Cache管理器可以通过设置--cache-max-entry-count
参数,控制KV缓存占用剩余显存的最大比例。默认的比例为0.8。
2.使用W4A16量化
LMDeploy使用AWQ算法,实现模型4bit权重量化。推理引擎TurboMind提供了非常高效的4bit推理cuda kernel,性能是FP16的2.4倍以上。它支持以下NVIDIA显卡:
- 图灵架构(sm75):20系列、T4
- 安培架构(sm80,sm86):30系列、A10、A16、A30、A100
- Ada Lovelace架构(sm90):40 系列
LMDeploy服务(serve)
在本地直接推理大模型,这种方式成为本地部署。在生产环境下,我们有时会将大模型封装为API接口服务,供客户端访问。
我们把从架构上把整个服务流程分成下面几个模块。
- 模型推理/服务。主要提供模型本身的推理,一般来说可以和具体业务解耦,专注模型推理本身性能的优化。可以以模块、API等多种方式提供。
- API Server。中间协议层,把后端推理/服务通过HTTP,gRPC或其他形式的接口,供前端调用。
- Client。可以理解为前端,与用户交互的地方。通过通过网页端/命令行去调用API接口,获取模型推理/服务。
值得说明的是,以上的划分是一个相对完整的模型,但在实际中这并不是绝对的。比如可以把“模型推理”和“API Server”合并,有的甚至是三个流程打包在一起提供服务。