大语言模型llama-2-7b推理服务实战
1.概念
一般来说,参数量越大的模型效果会更好,但相对应的模型运行时产生的费用和微调训练所需要的数据量都会更多。
大语言模型llama-2-7b推理过程如下:
数据准备:下载llama-2-7b-hf模型,可以使用Hugging Face Transformers或PyTorch等库加载模型;准备要输入到模型中的数据,以及tokenizer对文本进行编码,以及将编码后的文本转换为模型所需的张量格式。
模型转换:在训练完成后,将训练时保存好的微调模型文件(Checkpoint Model)转换为可以直接推理的二进制格式文件.
模型推理:模型推理中模型会根据输入的文本生成相应的输出文本。
以上是大语言模型llama-2-7b的推理过程,这个过程需要大量的计算资源和时间。
2.模型下载
模型下载:
在HuggingFace中心(https://huggingface.co/meta-llama)模型列表页中可以看到多个来自不同开源社区的主流模型。在展示中名称中带有hf的模型已转换为Hugging Face检查点,因此无需进一步转换,我们将使用llama-2-7b-hf模型。
图1.1 huggingface模型列表
# 下载 llama-2-7b-hf模型
git clone https://huggingface.co/meta-llama/Llama-2-7b-hf
- tokenizer下载
tokenizer需要下载上述对应模型版本的tokenizer.model,也可以从Hugging Face模型存储库中下载并使用tokenizer。
# 下载 tokenizer
https://github.com/huggingface/tokenizers.git
tokenizer主要完成的工作:
1.分词:将文本数据分词为字或者字符;
2.构建词典:根据数据集分词的结果,构建词典。(这一步并不绝对,如果采用预训练词向量,词典映射要根据词向量文件进行处理)。
3.数据转换:根据构建好的词典,将分词处理后的数据做映射,将文本序列转换为数字序列。数字序列还要变成符合模型需求的tensor格式。
4.数据填充与截断:在以batch输入到模型的方式中,需要对过短的数据进行填充,过长的数据进行截断,保证数据长度符合模型能接受的范围,同时batch内的数据维度大小一致,否则无法成批次变成tensor张量。
- 模型转换
模型转换指的是将训练时保存好的微调模型文件(Checkpoint Model)转换为可以直接推理的二进制格式文件,以便能够直接用于推理。这种二进制格式通常是为了加速推理而设计的,它可能包括模型的优化版本、减少冗余数据、固定模型结构等操作。
使用llama-2-7b-hf模型无需进行模型转换,当选择llama-2-7b模型需要将llama-2-7b模型转换为HuggingFace 格式。
使用huggingface transformers提供的脚本convert_llama_weights_to_hf.py,将原版llama模型转换为HuggingFace格式。
同时需要将原版llama-2-7b的tokenizer.model放在--input_dir指定的目录,其余文件放在${input_dir)/${model_size)下。执行以下命令后,--output_dir中将存放转换好的hf版权重。
注意:transformers版本必须是4.31.0或以上版本,否则会报错。
# 下载 transformers
git clone gitegithub.com:huggingface/transformers.git
# 进入到脚本所在目录下
cd transformers/src/transformers/models/llama
#运行转换脚本
python convert_llama_weights_to_hf.py
--input_dir /llama-2-7b \
--model_size 7B \
--output_dir /users/tgl/Downloads/llama_models/7B_hf/
3.模型推理
vLLM是是伯克利大学LMSYS组织开源的大语言模型高速推理框架,一个基于剪枝技术的大模型推理加速工具,通过去除模型中的冗余参数,极大地提升实时场景下的语言模型服务的吞吐与内存使用效率,可以在保证模型性能的同时显著减少推理时间。vLLM是一个快速且易于使用的库,用于LLM推理和服务,可以和HuggingFace无缝集成。
图2.1 模型推理流程
vLLM的架构中它的核心组件是LLMEngine类,外层接口类LLM和AsyncLLMEngine都是对LLMEngine的封装。LLMEngine有两个核心组件,分别是负责请求调度的Scheduler和负责模型推理的Worker,前者从等待队列中选择接下来要处理的请求,后者负责使用模型对被调度的请求进行推理。
图2.2 vllm架构
LLMEngine是整个系统的入口,它接收输入请求并执行推理过程。在初始化阶段,LLMEngine会调用Worker中的CacheEngine来初始化GPU和CPU内存,并计算可用的block数量。每个输入请求会构造一个SequenceGroup,并将其保存到Scheduler中进行进一步的调度和处理。通过多次执行step操作,LLMEngine会完成所有输入请求对应的SequenceGroup的生成。
Scheduler负责调度和管理待处理的SequenceGroup。它维护着三个队列:waiting、running和swapped。当一个SequenceGroup被添加到系统中时,它会被放入waiting队列中。Scheduler会根据调度策略从不同队列中选择SequenceGroup进行处理,并维护队列之间的状态。当一个SequenceGroup的推理过程新增了token时,Scheduler会更新该SequenceGroup的状态。
BlockSpaceManager负责维护Cache block和GPU/CPU内存之间的映射关系。它记录了每个Cache block在GPU显存或CPU内存中的物理地址。当一个SequenceGroup被加入Scheduler时,并没有分配具体的Cache block空间。在首次进入running阶段时,SequenceGroup会向BlockSpaceManager申请可用的block空间,并进行相应的分配和管理。
Worker负责缓存更新和LLM推理的执行。它首先执行缓存更新操作,然后准备输入token序列。通过调用LLM模型进行推理,Worker会生成新的token,并将其输出结果更新到对应的SequenceGroup中。最后,多次执行step操作,直到所有输入请求对应的SequenceGroup都完成生成。
CacheEngine作为Worker的一部分,负责具体的缓存操作。它执行缓存的换入、换出、拷贝等操作,并与BlockSpaceManager协同工作,管理GPU和CPU内存之间的数据传输。
制作镜像
通过dockerfile文件制作环境镜像,可以在不同的云主机上轻松地复制和部署模型训练环境,从而确保所有依赖项和配置都是正确的、提高模型推理的效率。 vLLM框架环境镜像制作dockerfile文件如下:
# dockerfile
FROM nvidia/cuda:12.1.0-devel-ubuntu22.04 AS dev
RUN apt-get update -y \
&& apt-get install -y python3-pip git
RUN ldconfig /usr/local/cuda-12.1/compat/
WORKDIR /workspace
COPY requirements-common.txt requirements-common.txt
COPY requirements-cuda.txt requirements-cuda.txt
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements-cuda.txt
COPY requirements-dev.txt requirements-dev.txt
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements-dev.txt
ARG torch_cuda_arch_list='7.0 7.5 8.0 8.6 8.9 9.0+PTX'
ENV TORCH_CUDA_ARCH_LIST=${torch_cuda_arch_list}
快速部署
模型推理指的是运行转换后的二进制格式文件,接收新的、未见过的数据样本,根据其已学习到的特征和模式,生成预测结果。
下面我们就用yaml文件创建模型推理的服务,首先创建一个目录用来存放模型推理的yaml文件。
mkdir -p /root/yaml/inference
cd /root/yaml/inference
模型推理的vllm.yaml文件如下:
apiVersion: v1
kind: InferenceService
metadata:
name: vllm #实例名称
namespace: aiops-system #命名空间
spec:
predictor:
containers:
- args:
- --host
- "0.0.0.0"
- --port
- "8080" #推理服务的端口号
- --model
- /mnt/models/data/out_put/ #模型转换后的路径
command:
- python3
- -m
- vllm.entrypoints.api_server
env:
- name: STORAGE_URI
value: pvc://is-pvc-1
image: vllmserver:latest
name: kserve-container
resources:
limits:
cpu: "4"
memory: 20Gi
nvidia.com/gpu: "4"
requests:
cpu: "2"
memory: 20Gi
nvidia.com/gpu: "4"
通过vllm.yaml文件创建模型推理任务,相关联的pod会对应一起生成,在master节点上执行创建pod命令。
# k8s创建InferenceService
kubectl create -f vllm.yaml
之后就看到pod成功启动了,查看已创建的pod,以及pod的状态信息。
# 查看pod
kubectl get pod -n aiops-system
图2.3 推理服务pod的状态信息
推理服务启动后查看 pod的ip。
# 查看pod的ip地址
kubectl get pod vllm-predictor-674d78bdc9-m24d4 -n aiops-system -o wide
图2.4 推理服务pod的ip信息
模型推理问答的命令。
# prompt输入到模型中的数据
curl -X POST -H "Content-Type: application/json" -d '{"prompt":"My name is"}' http://172.19.***.**:8080/generate
图2.5 推理服务问答
3.总结
综上所述,llama-2-7b大语言模型推理服务的实战应用展示了其在自然语言处理领域的强大实力和应用潜力。通过不断的技术优化和服务改进,我们可以进一步推动自然语言处理技术的发展,为用户提供更好的体验和价值。未来,我们可以期待更先进的模型、更智能的推理服务以及更广泛的应用场景。
本文转载自 AI遇见云,作者:贺晴