书生·浦语大模型开源体系(五)笔记

💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢迎在文章下方留下你的评论和反馈。我期待着与你分享知识、互相学习和建立一个积极的社区。谢谢你的光临,让我们一起踏上这个知识之旅!

文章目录

🍀LMDeploy模型对话(chat)

下载模型

本次实战营已经在开发机的共享目录中准备好了常用的预训练模型,可以运行如下命令查看:

bash 复制代码
ls /root/share/new_models/Shanghai_AI_Laboratory/

InternStudio开发机上下载模型(推荐)

如果你是在InternStudio开发机上,可以按照如下步骤快速下载模型。

首先进入一个你想要存放模型的目录,本教程统一放置在Home目录。执行如下指令:

bash 复制代码
cd ~

然后执行如下指令由开发机的共享目录软链接或拷贝模型:

bash 复制代码
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/

执行完如上指令后,可以运行"ls"命令。可以看到,当前目录下已经多了一个internlm2-chat-1_8b文件夹,即下载好的预训练模型。

bash 复制代码
ls

使用Transformer库运行模型

ransformer库是Huggingface社区推出的用于运行HF模型的官方库。

在2.2中,我们已经下载好了InternLM2-Chat-1.8B的HF模型。下面我们先用Transformer来直接运行InternLM2-Chat-1.8B模型,后面对比一下LMDeploy的使用感受。

现在,让我们点击左上角的图标,打开VSCode。

在左边栏空白区域单击鼠标右键,点击Open in Intergrated Terminal。

等待片刻,打开终端。

在终端中输入如下指令,新建pipeline_transformer.py。

bash 复制代码
touch /root/pipeline_transformer.py

回车执行指令,可以看到侧边栏多出了pipeline_transformer.py文件,点击打开。后文中如果要创建其他新文件,也是采取类似的操作。

将以下内容复制粘贴进入pipeline_transformer.py。

bash 复制代码
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)

按Ctrl+S键保存(Mac用户按Command+S)。

回到终端,激活conda环境。

bash 复制代码
conda activate lmdeploy

运行python代码:

bash 复制代码
python /root/pipeline_transformer.py

使用LMDeploy与模型对话

这一小节我们来介绍如何应用LMDeploy直接与模型进行对话。

首先激活创建好的conda环境:

bash 复制代码
conda activate lmdeploy

使用LMDeploy与模型进行对话的通用命令格式为:

bash 复制代码
lmdeploy chat [HF格式模型路径/TurboMind格式模型路径]

例如,您可以执行如下命令运行下载的1.8B模型:

bash 复制代码
lmdeploy chat /root/internlm2-chat-1_8b

下面我们就可以与InternLM2-Chat-1.8B大模型对话了。比如输入"请给我讲一个小故事吧",然后按两下回车键。

速度是不是明显比原生Transformer快呢~当然,这种感受可能不太直观,感兴趣的佬可以查看拓展部分"6.3 定量比较LMDeploy与Transformer库的推理速度"。

输入"exit"并按两下回车,可以退出对话。

拓展内容:有关LMDeploy的chat功能的更多参数可通过-h命令查看。

bash 复制代码
lmdeploy chat -h

🍀LMDeploy模型量化(lite)

本部分内容主要介绍如何对模型进行量化。主要包括 KV8量化和W4A16量化。总的来说,量化是一种以参数或计算中间结果精度下降换空间节省(以及同时带来的性能提升)的策略。

正式介绍 LMDeploy 量化方案前,需要先介绍两个概念:

计算密集(compute-bound): 指推理过程中,绝大部分时间消耗在数值计算上;针对计算密集型场景,可以通过使用更快的硬件计算单元来提升计算速度。

访存密集(memory-bound): 指推理过程中,绝大部分时间消耗在数据读取上;针对访存密集型场景,一般通过减少访存次数、提高计算访存比或降低访存量来优化。

常见的 LLM 模型由于 Decoder Only 架构的特性,实际推理时大多数的时间都消耗在了逐 Token 生成阶段(Decoding 阶段),是典型的访存密集型场景。

那么,如何优化 LLM 模型推理中的访存密集问题呢? 我们可以使用KV8量化和W4A16量化。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全部存储于显存,以加快访存速度。当显存空间不足时,也可以将KV Cache放在内存,通过缓存管理器控制将当前需要使用的数据放入显存。

模型在运行时,占用的显存可大致分为三部分:模型参数本身占用的显存、KV Cache占用的显存,以及中间运算结果占用的显存。LMDeploy的KV Cache管理器可以通过设置--cache-max-entry-count参数,控制KV缓存占用剩余显存的最大比例。默认的比例为0.8。

下面通过几个例子,来看一下调整--cache-max-entry-count参数的效果。首先保持不加该参数(默认0.8),运行1.8B模型。

bash 复制代码
lmdeploy chat /root/internlm2-chat-1_8b

与模型对话,查看右上角资源监视器中的显存占用情况。

此时显存占用为7856MB。下面,改变--cache-max-entry-count参数,设为0.5。

bash 复制代码
lmdeploy chat /root/internlm2-chat-1_8b --cache-max-entry-count 0.5

与模型对话,再次查看右上角资源监视器中的显存占用情况。

看到显存占用明显降低,变为6608M。

下面来一波"极限",把--cache-max-entry-count参数设置为0.01,约等于禁止KV Cache占用显存。

bash 复制代码
lmdeploy chat /root/internlm2-chat-1_8b --cache-max-entry-count 0.01

然后与模型对话,可以看到,此时显存占用仅为4560MB,代价是会降低模型推理速度。

使用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 系列

运行前,首先安装一个依赖库。

bash 复制代码
pip install einops==0.7.0

仅需执行一条命令,就可以完成模型量化工作。

bash 复制代码
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

运行时间较长,请耐心等待。量化工作结束后,新的HF模型被保存到internlm2-chat-1_8b-4bit目录。下面使用Chat功能运行W4A16量化后的模型。

bash 复制代码
lmdeploy chat /root/internlm2-chat-1_8b-4bit --model-format awq

为了更加明显体会到W4A16的作用,我们将KV Cache比例再次调为0.01,查看显存占用情况。

bash 复制代码
lmdeploy chat /root/internlm2-chat-1_8b-4bit --model-format awq --cache-max-entry-count 0.01

可以看到,显存占用变为2472MB,明显降低。

拓展内容:有关LMDeploy的lite功能的更多参数可通过-h命令查看。

bash 复制代码
lmdeploy lite -h

🍀LMDeploy服务(serve)

在第二章和第三章,我们都是在本地直接推理大模型,这种方式成为本地部署。在生产环境下,我们有时会将大模型封装为API接口服务,供客户端访问。

我们来看下面一张架构图:

我们把从架构上把整个服务流程分成下面几个模块。

模型推理/服务。主要提供模型本身的推理,一般来说可以和具体业务解耦,专注模型推理本身性能的优化。可以以模块、API等多种方式提供。

API Server。中间协议层,把后端推理/服务通过HTTP,gRPC或其他形式的接口,供前端调用。

Client。可以理解为前端,与用户交互的地方。通过通过网页端/命令行去调用API接口,获取模型推理/服务。

值得说明的是,以上的划分是一个相对完整的模型,但在实际中这并不是绝对的。比如可以把"模型推理"和"API Server"合并,有的甚至是三个流程打包在一起提供服务。

启动API服务器

通过以下命令启动API服务器,推理internlm2-chat-1_8b模型:

bash 复制代码
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

其中,model-format、quant-policy这些参数是与第三章中量化推理模型一致的;server-name和server-port表示API服务器的服务IP与服务端口;tp参数表示并行数量(GPU数量)。

通过运行以上指令,我们成功启动了API服务器,请勿关闭该窗口,后面我们要新建客户端连接该服务。

可以通过运行一下指令,查看更多参数及使用方法:

bash 复制代码
lmdeploy serve api_server -h

你也可以直接打开http://{host}:23333查

注意,这一步由于Server在远程服务器上,所以本地需要做一下ssh转发才能直接访问。在你本地打开一个cmd窗口,输入命令如下:

bash 复制代码
ssh -CNg -L 23333:127.0.0.1:23333 root@ssh.intern-ai.org.cn -p 你的ssh端口号

命令行客户端连接API服务器

运行命令行客户端:

bash 复制代码
lmdeploy serve api_client http://localhost:23333

现在你使用的架构是这样的:

网页客户端连接API服务器

关闭刚刚的VSCode终端,但服务器端的终端不要关闭。

新建一个VSCode终端,激活conda环境。

bash 复制代码
conda activate lmdeploy

使用Gradio作为前端,启动网页客户端。

bash 复制代码
lmdeploy serve gradio http://localhost:23333 \
    --server-name 0.0.0.0 \
    --server-port 6006

现在你使用的架构是这样的:


🍀Python代码集成

Python代码集成运行1.8B模型

首先激活conda环境。

conda activate lmdeploy

新建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)

代码解读:

第1行,引入lmdeploy的pipeline模块

第3行,从目录"./internlm2-chat-1_8b"加载HF模型

第4行,运行pipeline,这里采用了批处理的方式,用一个列表包含两个输入,lmdeploy同时推理两个输入,产生两个输出结果,结果返回给response

第5行,输出response

保存后运行代码文件:

python /root/pipeline.py

向TurboMind后端传递参数

在第3章,我们通过向lmdeploy传递附加参数,实现模型的量化推理,及设置KV Cache最大占用比例。在Python代码中,可以通过创建TurbomindEngineConfig,向lmdeploy传递参数。

以设置KV Cache占用比例为例,新建python文件pipeline_kv.py。

bash 复制代码
touch /root/pipeline_kv.py

打开pipeline_kv.py,填入如下内容:

bash 复制代码
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

得到输出结果:

挑战与创造都是很痛苦的,但是很充实。

相关推荐
Yawesh_best5 小时前
告别系统壁垒!WSL+cpolar 让跨平台开发效率翻倍
运维·服务器·数据库·笔记·web安全
Ccjf酷儿7 小时前
操作系统 蒋炎岩 3.硬件视角的操作系统
笔记
习习.y7 小时前
python笔记梳理以及一些题目整理
开发语言·笔记·python
在逃热干面8 小时前
(笔记)自定义 systemd 服务
笔记
DKPT9 小时前
ZGC和G1收集器相比哪个更好?
java·jvm·笔记·学习·spring
QT 小鲜肉10 小时前
【孙子兵法之上篇】001. 孙子兵法·计篇
笔记·读书·孙子兵法
星轨初途11 小时前
数据结构排序算法详解(5)——非比较函数:计数排序(鸽巢原理)及排序算法复杂度和稳定性分析
c语言·开发语言·数据结构·经验分享·笔记·算法·排序算法
QT 小鲜肉12 小时前
【孙子兵法之上篇】001. 孙子兵法·计篇深度解析与现代应用
笔记·读书·孙子兵法
love530love14 小时前
【笔记】ComfUI RIFEInterpolation 节点缺失问题(cupy CUDA 安装)解决方案
人工智能·windows·笔记·python·插件·comfyui
愚戏师14 小时前
MySQL 数据导出
数据库·笔记·mysql