LMDeploy 的量化和部署
課程內(nèi)容
課程筆記
1 大模型部署背景
2 LMDeploy簡介
量化码俩,可以減低對顯存的要求窍育。
隊列中S0贾节、S1進來后,Slot從隊列中拉取S0和S1進行推理。
S2請求進入請求隊列,Slot有空閑槽位迈嘹,拉取S2進行推理。同時判斷S0推理完成全庸,將S0移出Slot秀仲。
S2完成,移出Slot壶笼。剩下S1繼續(xù)推理神僵。
S1推理完成,移出Slot覆劈。
實現(xiàn)了動態(tài)Batch保礼。大模型推理的新的處理方式,以前的生成模型责语、Encoder模型是一次把結(jié)果全部出來炮障。
理論上可以支持無限長。
分塊緩存k/v數(shù)據(jù)坤候,通過三種狀態(tài)來進行遷移铝阐。
顯存在推理過程中動態(tài)調(diào)整。
lmdeploy serve api_server InternLM/internlm-chat-7b-model-name internlm-chat-7b--server-port 8080
Swagger地址:http://0.0.0.0:8080
models:列出你的模型列表
completion和chat completion
lmdeploy 的專有api
3 LMDeploy動手實踐環(huán)節(jié) - 安裝铐拐、部署徘键、量化
3.1 環(huán)境準備
# 復(fù)制conda環(huán)境,便于在此基礎(chǔ)上安裝新的軟件包
/root/share/install_conda_env_internlm_base.sh lmdeploy
# 激活lmdeploy環(huán)境
conda activate lmdeploy
可以進入Python檢查一下 PyTorch 和 lmdeploy 的版本遍蟋。由于 PyTorch 在官方提供的環(huán)境里吹害,我們應(yīng)該可以看到版本顯示,而 lmdeploy 需要我們自己安裝虚青,此處應(yīng)該會提示“沒有這個包”它呀,如下圖所示。
lmdeploy 沒有安裝棒厘,我們接下來手動安裝一下纵穿,建議安裝最新的穩(wěn)定版。 如果是在 InternStudio 開發(fā)環(huán)境奢人,需要先運行下面的命令谓媒,否則會報錯。
# 解決 ModuleNotFoundError: No module named 'packaging' 問題
pip install packaging
# 使用 flash_attn 的預(yù)編譯包解決安裝過慢問題
pip install /root/share/wheels/flash_attn-2.4.2+cu118torch2.0cxx11abiTRUE-cp310-cp310-linux_x86_64.whl
# 安裝lmdeploy包
pip install 'lmdeploy[all]==v0.1.0'
由于默認安裝的是 runtime 依賴包何乎,但是我們這里還需要部署和量化句惯,所以,這里選擇 [all]支救。然后可以再檢查一下 lmdeploy 包抢野,如下圖所示。
基礎(chǔ)環(huán)境到這里就配置好了各墨。
3.2 服務(wù)部署
3.2.1 模型轉(zhuǎn)換
3.2.1.1 在線轉(zhuǎn)換
直接啟動本地的 Huggingface 模型指孤,如下所示。
# 加載使用 lmdeploy 量化的版本
lmdeploy chat turbomind /share/temp/model_repos/internlm-chat-7b/ --model-name internlm-chat-7b
啟動一個本地對話界面贬堵,通過 Bash 可以與 LLM 進行對話恃轩。
3.2.1.2 離線轉(zhuǎn)換
離線轉(zhuǎn)換需要在啟動服務(wù)之前,將模型轉(zhuǎn)為 lmdeploy TurboMind 的格式扁瓢,如下所示详恼。
# 轉(zhuǎn)換模型(FastTransformer格式) TurboMind
lmdeploy convert internlm-chat-7b /path/to/internlm-chat-7b
這里我們使用官方提供的模型文件,就在用戶根目錄執(zhí)行引几,如下所示昧互。
lmdeploy convert internlm-chat-7b /root/share/temp/model_repos/internlm-chat-7b/
執(zhí)行完成后將會在當前目錄生成一個 workspace 的文件夾。這里面包含的就是 TurboMind 和 Triton “模型推理”需要到的文件伟桅。
目錄如下圖所示敞掘。
weights 和 tokenizer 目錄分別放的是拆分后的參數(shù)和 Tokenizer。如果我們進一步查看 weights 的目錄楣铁,就會發(fā)現(xiàn)參數(shù)是按層和模塊拆開的玖雁,如下圖所示。
每一份參數(shù)第一個 0 表示“層”的索引盖腕,后面的那個0表示 Tensor 并行的索引赫冬,因為我們只有一張卡浓镜,所以被拆分成 1 份。如果有兩張卡可以用來推理劲厌,則會生成0和1兩份膛薛,也就是說,會把同一個參數(shù)拆成兩份补鼻。比如 layers.0.attention.w_qkv.0.weight 會變成 layers.0.attention.w_qkv.0.weight 和 layers.0.attention.w_qkv.1.weight哄啄。執(zhí)行 lmdeploy convert 命令時,可以通過 --tp 指定(tp 表示 tensor parallel)风范,該參數(shù)默認值為1(也就是一張卡)咨跌。
3.2.2 TurboMind 推理+命令行本地對話
模型轉(zhuǎn)換完成后,我們就具備了使用模型推理的條件硼婿,接下來就可以進行真正的模型推理環(huán)節(jié)锌半。
我們先嘗試本地對話(Bash Local Chat),下面用(Local Chat 表示)在這里其實是跳過 API Server 直接調(diào)用 TurboMind加酵。簡單來說拳喻,就是命令行代碼直接執(zhí)行 TurboMind。所以說猪腕,實際和前面的架構(gòu)圖是有區(qū)別的冗澈。
這里支持多種方式運行,比如Turbomind陋葡、PyTorch亚亲、DeepSpeed。但 PyTorch 和 DeepSpeed 調(diào)用的其實都是 Huggingface 的 Transformers 包腐缤,PyTorch表示原生的 Transformer 包捌归,DeepSpeed 表示使用了 DeepSpeed 作為推理框架。Pytorch/DeepSpeed 目前功能都比較弱岭粤,不具備生產(chǎn)能力惜索,不推薦使用。
執(zhí)行命令如下剃浇。
# Turbomind + Bash Local Chat
lmdeploy chat turbomind ./workspace
啟動后就可以和它進行對話了巾兆,如下圖所示。
輸入后兩次回車虎囚,退出時輸入exit 回車兩次即可角塑。此時,Server 就是本地跑起來的模型(TurboMind)淘讥,命令行可以看作是前端圃伶。
3.2.3 TurboMind推理+API服務(wù)
在上面的部分我們嘗試了直接用命令行啟動 Client,接下來我們嘗試如何運用 lmdepoy 進行服務(wù)化。
”模型推理/服務(wù)“目前提供了 Turbomind 和 TritonServer 兩種服務(wù)化方式窒朋。此時搀罢,Server 是 TurboMind 或 TritonServer,API Server 可以提供對外的 API 服務(wù)炼邀。我們推薦使用 TurboMind魄揉,TritonServer 使用方式詳見《附錄1》。
首先拭宁,通過下面命令啟動服務(wù)。
# ApiServer+Turbomind api_server => AsyncEngine => TurboMind
lmdeploy serve api_server ./workspace \
--server_name 0.0.0.0 \
--server_port 23333 \
--instance_num 64 \
--tp 1
上面的參數(shù)中 server_name 和 server_port 分別表示服務(wù)地址和端口瓣俯,tp 參數(shù)我們之前已經(jīng)提到過了杰标,表示 Tensor 并行。還剩下一個 instance_num 參數(shù)彩匕,表示實例數(shù)腔剂,可以理解成 Batch 的大小。執(zhí)行后如下圖所示驼仪。
然后掸犬,我們可以新開一個窗口,執(zhí)行下面的 Client 命令绪爸。如果使用官方機器湾碎,可以打開 vscode 的 Terminal,執(zhí)行下面的命令奠货。
# ChatApiClient+ApiServer(注意是http協(xié)議介褥,需要加http)
lmdeploy serve api_client http://localhost:23333
如下圖所示。
當然递惋,剛剛我們啟動的是 API Server柔滔,自然也有相應(yīng)的接口∑妓洌可以直接打開 http://{host}:23333 查看睛廊,如下圖所示。
注意杉编,這一步由于 Server 在遠程服務(wù)器上超全,所以本地需要做一下 ssh 轉(zhuǎn)發(fā)才能直接訪問(與第一部分操作一樣),命令如下:
ssh -CNg -L 23333:127.0.0.1:23333 root@ssh.intern-ai.org.cn -p <你的ssh端口號>
這里一共提供了 4 個 HTTP 的接口王财,任何語言都可以對其進行調(diào)用卵迂,我們以 v1/chat/completions 接口為例,簡單試一下绒净。
接口請求參數(shù)如下:
{
"model": "internlm-chat-7b",
"messages": "寫一首春天的詩",
"temperature": 0.7,
"top_p": 1,
"n": 1,
"max_tokens": 512,
"stop": false,
"stream": false,
"presence_penalty": 0,
"frequency_penalty": 0,
"user": "string",
"repetition_penalty": 1,
"renew_session": false,
"ignore_eos": false
}
請求結(jié)果如下见咒。
3.2.4 網(wǎng)頁 Demo 演示
這一部分主要是將 Gradio 作為前端 Demo 演示。在上一節(jié)的基礎(chǔ)上挂疆,我們不執(zhí)行后面的 api_client 或 triton_client改览,而是執(zhí)行 gradio下翎。
由于 Gradio 需要本地訪問展示界面,因此也需要通過 ssh 將數(shù)據(jù)轉(zhuǎn)發(fā)到本地宝当。命令如下:
ssh -CNg -L 6006:127.0.0.1:6006 root@ssh.intern-ai.org.cn -p <你的 ssh 端口號>
3.2.4.1 TurboMind 服務(wù)作為后端
API Server 的啟動和上一節(jié)一樣视事,這里直接啟動作為前端的 Gradio。
# Gradio+ApiServer庆揩。必須先開啟 Server俐东,此時 Gradio 為 Client
lmdeploy serve gradio http://0.0.0.0:23333 \
--server_name 0.0.0.0 \
--server_port 6006 \
--restful_api True
結(jié)果如下圖所示。
3.2.4.2 TurboMind 推理作為后端
當然订晌,Gradio 也可以直接和 TurboMind 連接虏辫,如下所示。
# Gradio+Turbomind(local)
lmdeploy serve gradio ./workspace
可以直接啟動 Gradio锈拨,此時沒有 API Server砌庄,TurboMind 直接與 Gradio 通信。如下圖所示奕枢。
3.2.5 TurboMind 推理 + Python 代碼集成
前面介紹的都是通過 API 或某種前端與”模型推理/服務(wù)“進行交互娄昆,lmdeploy 還支持 Python 直接與 TurboMind 進行交互,如下所示缝彬。
from lmdeploy import turbomind as tm
# load model
model_path = "/root/share/temp/model_repos/internlm-chat-7b/"
tm_model = tm.TurboMind.from_pretrained(model_path, model_name='internlm-chat-20b')
generator = tm_model.create_instance()
# process query
query = "你好啊兄嘚"
prompt = tm_model.model.get_prompt(query)
input_ids = tm_model.tokenizer.encode(prompt)
# inference
for outputs in generator.stream_infer(
session_id=0,
input_ids=[input_ids]):
res, tokens = outputs[0]
response = tm_model.tokenizer.decode(res.tolist())
print(response)
在上面的代碼中萌焰,我們首先加載模型,然后構(gòu)造輸入跌造,最后執(zhí)行推理杆怕。
加載模型可以顯式指定模型路徑,也可以直接指定 Huggingface 的 repo_id壳贪,還可以使用上面生成過的 workspace陵珍。這里的 tm.TurboMind 其實是對 C++ TurboMind 的封裝。
構(gòu)造輸入這里主要是把用戶的 query 構(gòu)造成 InternLLM 支持的輸入格式违施,比如上面的例子中互纯, query 是“你好啊兄嘚”,構(gòu)造好的 Prompt 如下所示磕蒲。
"""
<|System|>:You are an AI assistant whose name is InternLM (書生·浦語).
- InternLM (書生·浦語) is a conversational language model that is developed by Shanghai AI Laboratory (上海人工智能實驗室). It is designed to be helpful, honest, and harmless.
- InternLM (書生·浦語) can understand and communicate fluently in the language chosen by the user such as English and 中文.
<|User|>:你好啊兄嘚
<|Bot|>:
"""
Prompt 其實就是增加了 <|System|> 消息和 <|User|> 消息(即用戶的 query)留潦,以及一個 <|Bot|> 的標記,表示接下來該模型輸出響應(yīng)了辣往。最終輸出的響應(yīng)內(nèi)容如下所示兔院。
"你好啊,有什么我可以幫助你的嗎站削?"