【InternLM】LMDeploy部署实践

news2025/2/8 5:30:28

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1598185.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零开始写一个RTSP服务器(三)RTP传输H.264

目录 一、RTP封装1.1 RTP数据结构1.2 源码 二、H.264的RTP打包2.1 H.264格式2.2 H.264的RTP打包方式2.3 H.264 RTP包的时间戳计算2.4 源码 三、H.264 RTP打包的sdp描述四、测试 本篇文章目标,使用vlc打开sdp文件后,可以观看到视频数据 一、RTP封装 1.1 …

实战:完美解决md图床问题-nginx图床-2024.4.16(测试成功)

目录 文章目录 目录1、前言图床简介搭建方式需求背景解决方案 2、配置过程1.部署nginx服务2.配置picgo3.配置rsync服务(可选) 3、测试验证关于我最后最后 1、前言 图床简介 对于写博客的朋友们来讲,图床这个东西一定不会陌生,而且在一定程度上也给大家…

MySQL8.0.20 下载与安装

一、下载 MySQL服务器下载安装: 官网社区版地址: https://downloads.mysql.com/archives/installer/ 二、安装 安装注意事项---成功秘诀 安装密码不要设置复杂了,千万要记住密码,比如root和mysql就很好;不要随意卸…

4.Spring AOP

4.1 Spring AOP的基本概念 4.1.1 AOP的概念 在业务处理代码中,通常都有日志记录、性能统计、安全控制、事务处理、异常处理等操作。尽管使用OOP可以通过封装或继承的方式达到代码的重用,但仍然存在同样的代码分散到各个方法中。因此,采用OO…

文件上传App,H5,小程序多端兼容

插件地址&#xff1a;https://ext.dcloud.net.cn/plugin?id5459 下载lsj-upload插件 代码如下 结构 <lsj-upload :option"option" :size"size" :formats"formats" :debug"debug":instantly"instantly" change"…

网络编程(现在不重要)

目录 网络编程三要素与InetAddress类的使用 软件架构 面临的主要问题 网络编程三要素&#xff08;对应三个问题&#xff09; InetAddress的使用 TCP与UDP协议剖析与TCP编程案例&#xff08;了解&#xff09; TCP协议 UDP协议 例子 UDP、URL网络编程 URL&#xff1a;&…

Android多线程:Handler runOnUiThread 异步消息处理机制

目录 一&#xff0c;Android中的多线程问题 1.模拟耗时工作 2.Android开启子线程 二&#xff0c;在子线程中更新UI 1.异步消息处理机制 Handler 2.使用runOnUiThread更新UI 一&#xff0c;Android中的多线程问题 Android用户界面是与用户交互的接口&#xff0c;对于用户的…

偏微分方程算法之混合边界差分

目录 一、研究对象 二、差分格式 2.1 向前欧拉格式 1. 中心差商 1.1.1 理论推导 1.1.2 算例实现 2. x0处向前差商&#xff0c;x1处向后差商 1.2.1 理论推导 1.2.2 算例实现 2.2 Crank-Nicolson格式 2.2.1 理论推导 2.2.2 算例实现 一、研究对象 这里我们以混合边界…

科技云报道:AI大模型疯长,存储扛住了吗?

科技云报道原创。 AI大模型正在倒逼数字基础设施产业加速升级。 过去一年半&#xff0c;AI大模型标志性的应用相继出现&#xff0c;从ChatGPT到Sora一次次刷新人们的认知。震撼的背后&#xff0c;是大模型参数指数级的增长。 这种数据暴涨的压力&#xff0c;快速传导到了大模…

Efficient Multimodal learning from data-centric perspective

[MLLM-小模型推荐-2024.3.18] Bunny 以数据的眼光看问题 - 知乎近期几天会梳理下多模态小模型相关的论文&#xff0c;做个汇总。为了能够每天更新点啥&#xff0c;先穿插一些小模型算法。等到全部算法都梳理完成后&#xff0c;再发布一篇最终汇总版本的。 3.15 号 BAAI 发布了 …

关于机器学习/深度学习的一些事-答知乎问(五)

嵌入学习方法在解决小样本学习问题时面临的挑战是什么&#xff1f; &#xff08;1&#xff09;过度依赖于辅助数据&#xff0c;预训练的模式违背了小样本学习的本质定义。几乎所有的嵌入学习方法都需要通过大量辅助样本来预训练特征嵌入函数&#xff0c;但在实际应用场景中&am…

葡萄书--图理论基础

图的定义 G{V,E} 节点和边的信息可以是类别型的&#xff0c;类别型数据的取值只能是哪一类别。一般称类别型的信息为标签。 节点和边的信息可以是数值型的&#xff0c;数值型数据的取值范围为实数。一般称数值型的信息为属性。 在图的计算任务中&#xff0c;我们认为&#x…

不消除存储瓶颈,AIGC就是梦幻泡影

大数据产业创新服务媒体 ——聚焦数据 改变商业 在大模型和AIGC的新纪元&#xff0c;我们正见证一个前所未有的技术革命。从更自然的人机对话&#xff0c;到图片、视频生成&#xff0c;AIGC技术正在彻底改变我们创造、学习和交流的方式。 然而&#xff0c;这一切进步的背后&am…

【数据结构|C语言版】顺序表应用

前言1. 基于动态顺序表实现通讯录1.1 通讯录功能1.2 代码实现1.2.1 SeqList.h1.2.2 SeqList.c1.2.3 Contact.h1.2.4 Contact.c1.2.5 test.c 1.3 控制台测试1.3.1 添加联系人1.3.2 删除联系人1.3.3 修改联系人1.3.4 查找联系人1.3.5 清空通讯录1.3.6 通讯录读档和存档 2. 好题测…

如何打开一个fbx模型

步骤 ① 下载fbx viewer &#xff0c;以下是管网链接 FBX Review | Cross-platform 3D model viewer | Autodesk ②需要用邮箱进行注册&#xff0b;确认&#xff0c;这一步完成之后 ③下载之后吧fbx文件导入到这个里面就可以了

NL2SQL进阶系列(4):ConvAI、DIN-SQL、C3-浙大、DAIL-SQL-阿里等16个业界开源应用实践详解[Text2SQL]

NL2SQL进阶系列(4)&#xff1a;ConvAI、DIN-SQL等16个业界开源应用实践详解[Text2SQL] NL2SQL基础系列(1)&#xff1a;业界顶尖排行榜、权威测评数据集及LLM大模型&#xff08;Spider vs BIRD&#xff09;全面对比优劣分析[Text2SQL、Text2DSL] NL2SQL基础系列(2)&#xff1a…

前端导出excel 接口处理和导出处理

如果按照一般的请求方式&#xff0c;接口会返回如下乱码 此时&#xff0c;接口其实已经请求成功了&#xff0c;只需要对乱码进行一下处理就行 1.请求方式处理 1.1 如果是直接使用axios进行请求 axios({method: get,url: url,params: params,//需要添加responseType: blob }…

采用分治法求含n个实数序列中的最大元素和次大元素(C语言)

目录 实验内容&#xff1a; 实验过程&#xff1a; 1.算法设计 2.程序清单 3.复杂度分析 4.运行结果 实验内容&#xff1a; 设计一个程序&#xff0c;采用分治法求含n个实数序列中的最大元素和次大元素&#xff0c;并分析算法的时间复杂度。 实验过程&#xff1a; 1.算法…

深度学习之PyTorch实现卷积神经网络(CNN)

在深度学习领域&#xff0c;卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;CNN&#xff09;是一种非常强大的模型&#xff0c;专门用于处理图像数据。CNN通过卷积操作和池化操作来提取图像中的特征&#xff0c;具有较好的特征学习能力&#xff0c;特别适用…

华为OD机试 - 连续天数的最高利润额(Java 2024 C卷 100分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…