大語(yǔ)言模型llama-2-7b推理服務(wù)實(shí)戰(zhàn)
1.概念
一般來(lái)說(shuō),參數(shù)量越大的模型效果會(huì)更好,但相對(duì)應(yīng)的模型運(yùn)行時(shí)產(chǎn)生的費(fèi)用和微調(diào)訓(xùn)練所需要的數(shù)據(jù)量都會(huì)更多。
大語(yǔ)言模型llama-2-7b推理過(guò)程如下:
數(shù)據(jù)準(zhǔn)備:下載llama-2-7b-hf模型,可以使用Hugging Face Transformers或PyTorch等庫(kù)加載模型;準(zhǔn)備要輸入到模型中的數(shù)據(jù),以及tokenizer對(duì)文本進(jìn)行編碼,以及將編碼后的文本轉(zhuǎn)換為模型所需的張量格式。
模型轉(zhuǎn)換:在訓(xùn)練完成后,將訓(xùn)練時(shí)保存好的微調(diào)模型文件(Checkpoint Model)轉(zhuǎn)換為可以直接推理的二進(jìn)制格式文件.
模型推理:模型推理中模型會(huì)根據(jù)輸入的文本生成相應(yīng)的輸出文本。
以上是大語(yǔ)言模型llama-2-7b的推理過(guò)程,這個(gè)過(guò)程需要大量的計(jì)算資源和時(shí)間。
2.模型下載
模型下載:
在HuggingFace中心(???https://huggingface.co/meta-llama??)模型列表頁(yè)中可以看到多個(gè)來(lái)自不同開(kāi)源社區(qū)的主流模型。在展示中名稱中帶有hf的模型已轉(zhuǎn)換為Hugging Face檢查點(diǎn),因此無(wú)需進(jìn)一步轉(zhuǎn)換,我們將使用llama-2-7b-hf模型。
圖1.1 huggingface模型列表
# 下載 llama-2-7b-hf模型
git clone https://huggingface.co/meta-llama/Llama-2-7b-hf
- tokenizer下載
tokenizer需要下載上述對(duì)應(yīng)模型版本的tokenizer.model,也可以從Hugging Face模型存儲(chǔ)庫(kù)中下載并使用tokenizer。
# 下載 tokenizer
https://github.com/huggingface/tokenizers.git
tokenizer主要完成的工作:
1.分詞:將文本數(shù)據(jù)分詞為字或者字符;
2.構(gòu)建詞典:根據(jù)數(shù)據(jù)集分詞的結(jié)果,構(gòu)建詞典。(這一步并不絕對(duì),如果采用預(yù)訓(xùn)練詞向量,詞典映射要根據(jù)詞向量文件進(jìn)行處理)。
3.數(shù)據(jù)轉(zhuǎn)換:根據(jù)構(gòu)建好的詞典,將分詞處理后的數(shù)據(jù)做映射,將文本序列轉(zhuǎn)換為數(shù)字序列。數(shù)字序列還要變成符合模型需求的tensor格式。
4.數(shù)據(jù)填充與截?cái)啵涸谝詁atch輸入到模型的方式中,需要對(duì)過(guò)短的數(shù)據(jù)進(jìn)行填充,過(guò)長(zhǎng)的數(shù)據(jù)進(jìn)行截?cái)啵WC數(shù)據(jù)長(zhǎng)度符合模型能接受的范圍,同時(shí)batch內(nèi)的數(shù)據(jù)維度大小一致,否則無(wú)法成批次變成tensor張量。
- 模型轉(zhuǎn)換
模型轉(zhuǎn)換指的是將訓(xùn)練時(shí)保存好的微調(diào)模型文件(Checkpoint Model)轉(zhuǎn)換為可以直接推理的二進(jìn)制格式文件,以便能夠直接用于推理。這種二進(jìn)制格式通常是為了加速推理而設(shè)計(jì)的,它可能包括模型的優(yōu)化版本、減少冗余數(shù)據(jù)、固定模型結(jié)構(gòu)等操作。
使用llama-2-7b-hf模型無(wú)需進(jìn)行模型轉(zhuǎn)換,當(dāng)選擇llama-2-7b模型需要將llama-2-7b模型轉(zhuǎn)換為HuggingFace 格式。
使用huggingface transformers提供的腳本convert_llama_weights_to_hf.py,將原版llama模型轉(zhuǎn)換為HuggingFace格式。
同時(shí)需要將原版llama-2-7b的tokenizer.model放在--input_dir指定的目錄,其余文件放在${input_dir)/${model_size)下。執(zhí)行以下命令后,--output_dir中將存放轉(zhuǎn)換好的hf版權(quán)重。
注意:transformers版本必須是4.31.0或以上版本,否則會(huì)報(bào)錯(cuò)。
# 下載 transformers
git clone gitegithub.com:huggingface/transformers.git
# 進(jìn)入到腳本所在目錄下
cd transformers/src/transformers/models/llama
#運(yùn)行轉(zhuǎn)換腳本
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是是伯克利大學(xué)LMSYS組織開(kāi)源的大語(yǔ)言模型高速推理框架,一個(gè)基于剪枝技術(shù)的大模型推理加速工具,通過(guò)去除模型中的冗余參數(shù),極大地提升實(shí)時(shí)場(chǎng)景下的語(yǔ)言模型服務(wù)的吞吐與內(nèi)存使用效率,可以在保證模型性能的同時(shí)顯著減少推理時(shí)間。vLLM是一個(gè)快速且易于使用的庫(kù),用于LLM推理和服務(wù),可以和HuggingFace無(wú)縫集成。
圖2.1 模型推理流程
vLLM的架構(gòu)中它的核心組件是LLMEngine類,外層接口類LLM和AsyncLLMEngine都是對(duì)LLMEngine的封裝。LLMEngine有兩個(gè)核心組件,分別是負(fù)責(zé)請(qǐng)求調(diào)度的Scheduler和負(fù)責(zé)模型推理的Worker,前者從等待隊(duì)列中選擇接下來(lái)要處理的請(qǐng)求,后者負(fù)責(zé)使用模型對(duì)被調(diào)度的請(qǐng)求進(jìn)行推理。
圖2.2 vllm架構(gòu)
LLMEngine是整個(gè)系統(tǒng)的入口,它接收輸入請(qǐng)求并執(zhí)行推理過(guò)程。在初始化階段,LLMEngine會(huì)調(diào)用Worker中的CacheEngine來(lái)初始化GPU和CPU內(nèi)存,并計(jì)算可用的block數(shù)量。每個(gè)輸入請(qǐng)求會(huì)構(gòu)造一個(gè)SequenceGroup,并將其保存到Scheduler中進(jìn)行進(jìn)一步的調(diào)度和處理。通過(guò)多次執(zhí)行step操作,LLMEngine會(huì)完成所有輸入請(qǐng)求對(duì)應(yīng)的SequenceGroup的生成。
Scheduler負(fù)責(zé)調(diào)度和管理待處理的SequenceGroup。它維護(hù)著三個(gè)隊(duì)列:waiting、running和swapped。當(dāng)一個(gè)SequenceGroup被添加到系統(tǒng)中時(shí),它會(huì)被放入waiting隊(duì)列中。Scheduler會(huì)根據(jù)調(diào)度策略從不同隊(duì)列中選擇SequenceGroup進(jìn)行處理,并維護(hù)隊(duì)列之間的狀態(tài)。當(dāng)一個(gè)SequenceGroup的推理過(guò)程新增了token時(shí),Scheduler會(huì)更新該SequenceGroup的狀態(tài)。
BlockSpaceManager負(fù)責(zé)維護(hù)Cache block和GPU/CPU內(nèi)存之間的映射關(guān)系。它記錄了每個(gè)Cache block在GPU顯存或CPU內(nèi)存中的物理地址。當(dāng)一個(gè)SequenceGroup被加入Scheduler時(shí),并沒(méi)有分配具體的Cache block空間。在首次進(jìn)入running階段時(shí),SequenceGroup會(huì)向BlockSpaceManager申請(qǐng)可用的block空間,并進(jìn)行相應(yīng)的分配和管理。
Worker負(fù)責(zé)緩存更新和LLM推理的執(zhí)行。它首先執(zhí)行緩存更新操作,然后準(zhǔn)備輸入token序列。通過(guò)調(diào)用LLM模型進(jìn)行推理,Worker會(huì)生成新的token,并將其輸出結(jié)果更新到對(duì)應(yīng)的SequenceGroup中。最后,多次執(zhí)行step操作,直到所有輸入請(qǐng)求對(duì)應(yīng)的SequenceGroup都完成生成。
CacheEngine作為Worker的一部分,負(fù)責(zé)具體的緩存操作。它執(zhí)行緩存的換入、換出、拷貝等操作,并與BlockSpaceManager協(xié)同工作,管理GPU和CPU內(nèi)存之間的數(shù)據(jù)傳輸。
制作鏡像
通過(guò)dockerfile文件制作環(huán)境鏡像,可以在不同的云主機(jī)上輕松地復(fù)制和部署模型訓(xùn)練環(huán)境,從而確保所有依賴項(xiàng)和配置都是正確的、提高模型推理的效率。 vLLM框架環(huán)境鏡像制作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}
快速部署
模型推理指的是運(yùn)行轉(zhuǎn)換后的二進(jìn)制格式文件,接收新的、未見(jiàn)過(guò)的數(shù)據(jù)樣本,根據(jù)其已學(xué)習(xí)到的特征和模式,生成預(yù)測(cè)結(jié)果。
下面我們就用yaml文件創(chuàng)建模型推理的服務(wù),首先創(chuàng)建一個(gè)目錄用來(lái)存放模型推理的yaml文件。
mkdir -p /root/yaml/inference
cd /root/yaml/inference
模型推理的vllm.yaml文件如下:
apiVersion: v1
kind: InferenceService
metadata:
name: vllm #實(shí)例名稱
namespace: aiops-system #命名空間
spec:
predictor:
containers:
- args:
- --host
- "0.0.0.0"
- --port
- "8080" #推理服務(wù)的端口號(hào)
- --model
- /mnt/models/data/out_put/ #模型轉(zhuǎn)換后的路徑
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"
通過(guò)vllm.yaml文件創(chuàng)建模型推理任務(wù),相關(guān)聯(lián)的pod會(huì)對(duì)應(yīng)一起生成,在master節(jié)點(diǎn)上執(zhí)行創(chuàng)建pod命令。
# k8s創(chuàng)建InferenceService
kubectl create -f vllm.yaml
之后就看到pod成功啟動(dòng)了,查看已創(chuàng)建的pod,以及pod的狀態(tài)信息。
# 查看pod
kubectl get pod -n aiops-system
圖2.3 推理服務(wù)pod的狀態(tài)信息
推理服務(wù)啟動(dòng)后查看 pod的ip。
# 查看pod的ip地址
kubectl get pod vllm-predictor-674d78bdc9-m24d4 -n aiops-system -o wide
圖2.4 推理服務(wù)pod的ip信息
模型推理問(wèn)答的命令。
# prompt輸入到模型中的數(shù)據(jù)
curl -X POST -H "Content-Type: application/json" -d '{"prompt":"My name is"}' http://172.19.***.**:8080/generate
圖2.5 推理服務(wù)問(wèn)答
3.總結(jié)
綜上所述,llama-2-7b大語(yǔ)言模型推理服務(wù)的實(shí)戰(zhàn)應(yīng)用展示了其在自然語(yǔ)言處理領(lǐng)域的強(qiáng)大實(shí)力和應(yīng)用潛力。通過(guò)不斷的技術(shù)優(yōu)化和服務(wù)改進(jìn),我們可以進(jìn)一步推動(dòng)自然語(yǔ)言處理技術(shù)的發(fā)展,為用戶提供更好的體驗(yàn)和價(jià)值。未來(lái),我們可以期待更先進(jìn)的模型、更智能的推理服務(wù)以及更廣泛的應(yīng)用場(chǎng)景。
本文轉(zhuǎn)載自 ??AI遇見(jiàn)云??,作者:賀晴
