【InternLM】LMDeploy部署实践

本文详细介绍了LMDeploy,一款提供高效大模型压缩、部署和服务的工具,包括其特点如1.8倍的高请求吞吐量、INT4量化带来的性能提升、跨多机部署的便利以及kv缓存和W4A16量化对推理速度的优化。文章还展示了如何配置环境、模型下载和使用LMDeploy进行速度测试,以及如何设置kv缓存和量化策略来提高模型效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. LMDeploy基本介绍

LMDeploy提供一站式的大模型压缩、部署和服务,其主要特点包括:

  1. 高效的推理速度。通过引入持久批处理(即连续批处理)、阻塞 KV 缓存、动态拆分与融合、张量并行、高性能 CUDA 内核等关键特性,提供了比 vLLM 高1.8倍的请求吞吐量;
    (注:vLLM是一款开源的被广泛使用的大模型推理库,其支持大量的Hugging Face模型, LMDeploy广泛将vLLM作为对比对象)
  2. 高效的量化策略。LMDeploy支持权重和KV量化,INT4量化的推理速度是FP16的2.4被。量化效果已经得到了OpenCompass评估的验证。
  3. 方便的分布式部署。利用请求分发服务,LMDeploy 实现了跨多机和多卡的多模型服务的方便部署。
  4. 交互式推理模式。通过在多轮对话过程中缓存注意力的k/v,从而记住对话历史,避免历史会话的重复处理。

LMDeploy在A100卡上与vLLM的全面对比图如下:
在这里插入图片描述
目前LMDeploy支持的模型见下图,基本涵盖了主流的开源大模型:
在这里插入图片描述

2. 作业实践

2.1 环境配置

安装lmdeploy:pip install lmdeploy[all]==0.3.0
在这里插入图片描述

2.2 模型下载

测试模型为InternLM2-Chat-1.8B,利用git-lfs从OpenXLab平台进行下载:
step 1: 安装git-lfs组件

curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash
apt update
apt install git-lfs   
git lfs install  --system

step 2: 下载InternLM2-Chat-1.8B模型:

git clone https://code.openxlab.org.cn/OpenLMLab/internlm2-chat-1.8b.git

在这里插入图片描述

2.3 定量速度测试

简单对比下transformers和lmdeploy的推理速度。

采用原生transformers进行Internlm2-chat-1.8b的推理:

import torch
import datetime
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()

# warmup
inp = "hello"
for i in range(5):
    print("Warm up...[{}/5]".format(i+1))
    response, history = model.chat(tokenizer, inp, history=[])

# test speed
inp = "请创作一首五言绝句。"
times = 10
total_words = 0
start_time = datetime.datetime.now()
for i in range(times):
    response, history = model.chat(tokenizer, inp, history=history)
    total_words += len(response)
end_time = datetime.datetime.now()

delta_time = end_time - start_time
delta_time = delta_time.seconds + delta_time.microseconds / 1000000.0
speed = total_words / delta_time
print("Speed: {:.3f} words/s".format(speed))

整个的推理速度为Speed: 41.292 words/s(与token正向线性相关)
在这里插入图片描述

采用lmdeploy进行推理:

import datetime
from lmdeploy import pipeline

pipe = pipeline('/root/internlm2-chat-1_8b')

# warmup
inp = "hello"
for i in range(5):
    print("Warm up...[{}/5]".format(i+1))
    response = pipe([inp])

# test speed
inp = "请创作一首五言绝句。"
times = 10
total_words = 0
start_time = datetime.datetime.now()
for i in range(times):
    response = pipe([inp])
    total_words += len(response[0].text)
end_time = datetime.datetime.now()

delta_time = end_time - start_time
delta_time = delta_time.seconds + delta_time.microseconds / 1000000.0
speed = total_words / delta_time
print("Speed: {:.3f} words/s".format(speed))

整个的推理速度为Speed: 41.292 words/s(与token正向线性相关)
在这里插入图片描述

可见,测试样例上lmdeploy的推理速度为原生transformers的6倍。

2.4 设置KV Cache和W4A16量化

常见的 LLM 模型由于 Decoder Only 架构的特性,实际推理时大多数的时间都消耗在了逐 Token 生成阶段(Decoding 阶段),是典型的访存密集型场景。可通过缓存机制、量化算法等方法来优化LLM推理过程。

2.4.1 KV Cache基本概念

KV Cache是一种常用的大模型推理性能优化技术,其可以在不影响任何精度的前提下,通过时间换空间的思想,提升推理性能。

LLM作为生成式模型,其推理阶段是逐个token输出的,next token的推理会用到前面输出token和输入token的拼接,如何不断反复直到遇到终止符,其基本代码如下:

i = 0
with torch.no_grad():
    while out_token != token_eos:   # 根据词表定义的token_eos
        logits, _ = model(in_tokens)   # 前向推理
        out_token = torch.argmax(logits[-1, :], dim=0, keepdim=True)   # 贪婪解码
        in_tokens = torch.cat((in_tokens, out_token), 0)    # 输入拼接
        text = tokenizer.decode(in_tokens)   # 用作打印
        print(f'step {i} input: {text}', flush=True)
        i += 1

其输出效果类似于:

step 0 input: Lionel Messi is a player
step 1 input: Lionel Messi is a player who
step 2 input: Lionel Messi is a player who has
step 3 input: Lionel Messi is a player who has been
step 4 input: Lionel Messi is a player who has been a
step 5 input: Lionel Messi is a player who has been a key
step 6 input: Lionel Messi is a player who has been a key part
step 7 input: Lionel Messi is a player who has been a key part of
step 8 input: Lionel Messi is a player who has been a key part of the
step 9 input: Lionel Messi is a player who has been a key part of the team
step 10 input: Lionel Messi is a player who has been a key part of the team's
step 11 input: Lionel Messi is a player who has been a key part of the team's success
step 12 input: Lionel Messi is a player who has been a key part of the team's success.

这也就是为什么我们看到的绝大部分LLM应用采用流式输出的原因。

不难发现,随着拼接token的长度变长,推理过程的FLOPs会随之增大。另一方面,后面每个token的推理均用到了前面所有输出token的k-v值,其存在着重复计算的浪费。如果能够将前面输出token的k-v值缓存起来,那可以大大提升推理效率。如在transformers库中设置past_key_values参数,即可实现KV缓存的效果。当然其内部实现逻辑也是concat,不过是原KV缓存和新tokenKV值的concat。

with torch.no_grad():
    while out_token != token_eos:
        logits, kvcache = model(in_tokens, past_key_values=kvcache) # 增加了一个 past_key_values 的参数
        out_token = torch.argmax(logits[-1, :], dim=0, keepdim=True)
        in_tokens = out_token # 输出 token 直接作为下一轮的输入,不再拼接
        text = tokenizer.decode(in_tokens)
        print(f'step {i} input: {text}', flush=True)

采用KV Cache的方法,模型推理中的现存消耗主要可以分为三个部分:

2.4.2 W4A16量化基本概念

模型量化是一种重要的减小模型大小、提升模型推理效率的手段,其将神经网络的浮点计算转换为定点计算,从而将连续的无限值映射到一组较小的离散有限值。模型参数本身占用的显存、KV Cache占用的显存,以及中间运算结果占用的显存。

神经网络模型常见的权重数据格式有FP32(32位浮点,单精度)、FP16(半精度浮点)、INT8(8位整型)和INT4(4位整型)。如采用INT8格式,其相较于FP32可减小75%的模型大小。

按照量化阶段的不同,模型量化又可分为:训练时量化(quantization aware training, QAT)和训练后量化(post-training quantization, PTQ),QAT需要在训练阶段就对量化误差进行建模,一般能够获得较低的精度损失。PTQ 直接对普通训练后的模型进行量化,过程简单。

对于大模型而言,常见量化有两种设置:
1)W8A8 量化,即权重和激活都量化为 INT8;
2)W4A16量化,即权重量化为INT4,激活量化为FLOAT16.

适用于大模型的一些常见量化技术有:
在这里插入图片描述
以Qwen-7B-Chat为例,给出了量化后的效果对比。可见合理的采用量化技术,可以明显减小缓存、有效提升推理速度,同时保证模型的精度没有明显的损失。

  • 模型评估效果

在这里插入图片描述

  • 推理速度
    在这里插入图片描述

  • 显存使用
    在这里插入图片描述

2.4.3 LMDeploy的设置
  • KV Cache

LMDeploy的KV Cache管理器可以通过设置--cache-max-entry-count参数,控制KV缓存占用剩余显存的最大比例。默认的比例为0.8。

lmdeploy chat /root/internlm2-chat-1_8b --cache-max-entry-count 0.8

仍以internlm2-chat-1_8b模型为例进行试验,通过设置--cache-max-entry-count为不同值,可得到以下的表格:

cache-max-entry-count值模型显存大小(MiB)
0.8(默认值)20936
0.514792
0.16600
0.014712

随着参数值的减小,能感受到明显推理速度的减小。

  • W4A16量化

LMDeploy使用AWQ算法,实现模型4bit权重量化,同时推理引擎TurboMind提供了非常高效的4bit推理cuda kernel。

直接利用如下的命令下完成4bit的量化工作:

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

同样设置--cache-max-entry-count为不同值,观察模型占用现存的情况:

cache-max-entry-count值bit4量化后模型显存大小(MiB)
0.8(默认值)20516
0.513732
0.14708
0.012628

可见,通过量化手段可以有效减小模型的显存占用率,当然代价是会损失一定的推理精度。

2.4.4 KV Cache+W4A16量化 模型推理

下图为设置KV Cache最大占用比例为0.4,开启W4A16量化后,以命令行方式与模型对话:

lmdeploy chat /root/internlm2-chat-1_8b-4bit --model-format awq --cache-max-entry-count 0.4

在这里插入图片描述

2.5 API Server方式启动 lmdeploy

将大模型封装为API接口服务,可以更方便地让客户端用户进行调用,其电箱的服务流程结构图包括三个模块:
1)模型推理/服务。主要提供模型本身的推理,一般来说可以和具体业务解耦,专注模型推理本身性能的优化。可以以模块、API等多种方式提供。
2)API Server。中间协议层,把后端推理/服务通过HTTP,gRPC或其他形式的接口,供前端调用。
3)Client。可以理解为前端,与用户交互的地方。通过通过网页端/命令行去调用API接口,获取模型推理/服务。

上述三个模块组成的架构图如下:
在这里插入图片描述

2.5.1 启动后端

启动 lmdeploy后端,开启 W4A16量化,调整KV Cache的占用比例为0.4:

lmdeploy serve api_server \
    /root/internlm2-chat-1_8b-4bit \
    --model-format awq \
    --quant-policy 1 \
    --cache-max-entry-count 0.4 \
    --server-name 0.0.0.0 \
    --server-port 23333 \
    --tp 1

其背后使用FastAPI作为server,提供如下的接口功能:
在这里插入图片描述

2.5.2 命令行交互

命令行启动客户端:

lmdeploy serve api_client http://localhost:23333

运行后,可以通过命令行窗口直接与模型对话:
在这里插入图片描述

2.5.3 gradio客户端

使用gradio作为client,启动网页客户端并作简单测试:
在这里插入图片描述

2.6 使用Python代码集成的方式运行LMDeploy

lmdeploy效仿transformers库,提供了pipeline的端到端调用:

from lmdeploy import pipeline

pipe = pipeline('/root/internlm2-chat-1_8b')
response = pipe(['你好,请给我作一首诗', '离离原上草'])
print(response)

返回结果:
在这里插入图片描述

小模型的语义理解能力确实还是略显弱小,并没有正确理解本人的意图做出合理的回答。

在python代码中,同样可以设置KV Cache等参数。下面的示例使用W4A16量化,调整KV Cache的占用比例为0.4:

from lmdeploy import pipeline, TurbomindEngineConfig

# 调低 k/v cache内存占比调整为总显存的 40%
backend_config = TurbomindEngineConfig(cache_max_entry_count=0.4)

# 使用W4A16量化
pipe = pipeline('/root/internlm2-chat-1_8b-4bit',
                backend_config=backend_config)
response = pipe(['你好,请给我作一首诗', '离离原上草'])
print(response)

返回结果:
在这里插入图片描述
模型存在明显的幻觉现象,《离离原上草》是草根歌手周杰伦的代表作了。。。。

2.7 使用 LMDeploy 运行视觉多模态大模型

最新版本的LMDeploy支持了llava多模态模型,这里以llava-v1.6-7b进行推理:

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()   

上传了一张本人制作的流程图,这个居然也能回答的七七八八,确实很强大!

在这里插入图片描述

3. 参考资料

  1. https://github.com/InternLM/Tutorial/tree/camp2/lmdeploy
  2. https://docs.vllm.ai/en/latest/index.html
  3. https://github.com/InternLM/lmdeploy
  4. https://zhuanlan.zhihu.com/p/630832593
  5. https://zhuanlan.zhihu.com/p/671007819
<think>嗯,用户问的是如何使用LMDeploy部署大模型的具体步骤。首先,我需要回忆一下之前学过的关于LMDeploy的知识。记得引用里的内容提到过环境配置、服务部署、模型转换这些步骤。特别是引用[1]里详细说明了安装步骤和模型部署的方式,可能用户需要的是分步骤的指南。 首先,环境配置肯定是第一步。用户可能需要安装Python、LMDeploy库,可能还需要配置Conda环境。引用[1]提到要明确操作系统和安装步骤,所以应该先让用户安装Miniconda,然后创建环境,安装PyTorch和LMDeploy。这部分需要检查是否要包括CUDA的支持,因为大模型通常需要GPU加速。 接下来是模型下载。InternLM-Chat-7B这样的模型可能需要从Hugging Face或者ModelScope获取。这里需要确保用户知道如何下载模型,可能需要git lfs或者其他工具,但引用里没有详细说明下载步骤,可能需要提醒用户参考官方文档。 然后是模型转换部分,包括在线和离线转换。引用[3]提到使用不同模型进行量化,但用户可能用的是7B的模型,所以需要说明如何将HF格式转换为TurboMind格式。这里要提到lmdeploy convert命令,参数设置如model_name和model_format。 服务部署阶段,用户可能有不同的需求,比如本地对话、Gradio网页或者API服务。引用[1]和[4]提到多种部署方式,所以需要分别说明每个步骤。比如,启动API服务需要指定模型路径和端口,同时可能需要调整TP参数,根据GPU数量来设置。 模型量化部分,用户可能关心如何减小模型大小和提升速度。引用[3]提到量化需要较长时间,所以建议用户使用较小的模型进行测试。需要解释不同的量化方法,比如KV8和W4,以及如何执行这些量化命令。 最后,验证部署是否成功,可能需要运行测试脚本或者使用curl命令调用API,确保模型能正确响应。同时,用户可能遇到环境依赖问题,比如CUDA版本不匹配,或者显存不足,需要给出常见问题解答。 在思考过程中,还要注意用户可能的实际场景,比如是否在本地机器还是云服务器上部署,是否有足够的GPU资源。此外,引用[5]提到AutoDL平台,可能用户是在类似平台上操作,需要适配相关步骤。需要确保步骤清晰,命令准确,避免遗漏关键参数或配置。</think>### LMDeploy部署大模型详细步骤指南 #### 一、环境配置 1. **安装Miniconda**(推荐Python 3.10环境) ```bash wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh ``` 2. **创建虚拟环境** ```bash conda create -n lmdeploy python=3.10 -y conda activate lmdeploy ``` 3. **安装PyTorch与LMDeploy** ```bash pip install torch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 --index-url https://download.pytorch.org/whl/cu118 pip install lmdeploy[all] ``` #### 二、模型下载 以InternLM-Chat-7B为例: ```bash git clone https://www.modelscope.cn/Shanghai_AI_Laboratory/internlm2-chat-7b.git ``` #### 三、模型转换 1. **在线转换**(动态加载) ```bash lmdeploy chat /path/to/internlm2-chat-7b ``` 2. **离线转换**(生成TurboMind格式) ```bash lmdeploy convert internlm2-chat-7b --model-name internlm2-7b --model-format hf ``` #### 四、服务部署 1. **本地对话模式** ```bash lmdeploy chat ./workspace ``` 2. **网页Gradio部署** ```bash lmdeploy serve gradio ./workspace --server_name 0.0.0.0 --server_port 7860 ``` 3. **API服务部署** ```bash lmdeploy serve api_server ./workspace --server_name 0.0.0.0 --server_port 23333 --tp 1 ``` #### 五、模型量化(以W4A16为例) ```bash lmdeploy lite auto_awq /path/to/internlm2-chat-7b --calib-dataset ptb --calib-samples 128 --calib-seqlen 2048 --w-bits 4 --w-group-size 128 ``` #### 六、验证部署 ```python from lmdeploy import pipeline pipe = pipeline('./workspace') response = pipe(['你好']) print(response[0].text) ``` ### 关键参数说明 1. `--tp`:张量并行度,需与GPU数量匹配 2. `--cache-max-entry-count`:KV缓存比例,建议0.5-0.8 3. `--quant-policy`:量化策略,可选0(FP16)或4(INT4) ### 常见问题 1. **CUDA版本不匹配**:需确保CUDA版本与PyTorch对应(建议11.8+) 2. **显存不足**:可尝试量化或减小`--cache-max-entry-count` 3. **API调用示例**: ```bash curl http://localhost:23333/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "internlm2-7b", "messages": [{"role": "user", "content": "你好"}]}' ``` [^1][^3][^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值