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

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

文章目录

🍀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

得到输出结果:

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

相关推荐
m0_748256781 小时前
WebGIS实战开源项目:智慧机场三维可视化(学习笔记)
笔记·学习·开源
红色的山茶花1 小时前
YOLOv9-0.1部分代码阅读笔记-loss.py
笔记
胡西风_foxww4 小时前
【es6复习笔记】Promise对象详解(12)
javascript·笔记·es6·promise·异步·回调·地狱
吉大一菜鸡9 小时前
FPGA学习(基于小梅哥Xilinx FPGA)学习笔记
笔记·学习·fpga开发
CCSBRIDGE12 小时前
Magento2项目部署笔记
笔记
亦枫Leonlew13 小时前
微积分复习笔记 Calculus Volume 2 - 5.1 Sequences
笔记·数学·微积分
爱码小白13 小时前
网络编程(王铭东老师)笔记
服务器·网络·笔记
LuH112414 小时前
【论文阅读笔记】Learning to sample
论文阅读·笔记·图形渲染·点云
一棵开花的树,枝芽无限靠近你15 小时前
【PPTist】组件结构设计、主题切换
前端·笔记·学习·编辑器
犬余16 小时前
设计模式之桥接模式:抽象与实现之间的分离艺术
笔记·学习·设计模式·桥接模式