搭建一個大模型API服務

一蓑烟雨度平生發表於2024-03-01

搭建一個大模型API服務

本文將介紹如何使用SWIFT框架搭建一個大模型API服務,以方便後續做RAG、Agent的開發工作。

環境準備

基礎環境

  • 作業系統:Ubuntu 18.04.5 LTS (GNU/Linux 3.10.0-1127.el7.x86_64 x86_64)
  • Anaconda3:Anaconda3-2023.03-1-Linux-x86_64
  • 根據伺服器網路情況配置好conda源和pip源,此處使用的是超算山河源

建立一個新的conda環境:

conda create --name swift python=3.8

啟用剛剛建立的conda環境:

conda activate swift

下載SWIFT原始碼(v1.6.1):

git clone https://github.com/modelscope/swift.git

切換到SWIFT路徑:

cd /yldm0226/swift

安裝SWIFT:

pip install -e .[llm]

檢查伺服器cuda版本是否與當前安裝的pytorch對應,如果不對應,需要將pytorch版本降低到≤伺服器cuda版本;使用nvidia-smi檢視cuda版本:

當前cuda版本為11.7; 然後使用conda list檢查swift環境中pytorch的版本:

pytorch版本為2.2.0,從官網查詢可知2.2.0版本最低支援的cuda版本為11.8,這大於伺服器cuda版本11.7,因此需要將pytorch降低到支援cuda11.7的版本,從官網查詢可知目前最高的可支援cuda11.7的版本為2.0.1。執行下述命令更換pytorch版本:

pip install torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2

注:如果pytorch版本與伺服器cuda版本不對應,程式不會報錯,而是會輸出下面的警告,此時SWIFT會將模型權重載入到CPU上。推理速度非常慢:

UserWarning: CUDA initialization: The NVIDIA driver on your system is too old (found version 11070). Please update your GPU driver by downloading and installing a new version from the URL: http://www.nvidia.com/Download/index.aspx Alternatively, go to: https://pytorch.org to install a PyTorch version that has been compiled with your version of the CUDA driver. (Triggered internally at ../c10/cuda/CUDAFunctions.cpp:108.)

將大模型權重下載到本地,可以在ModelScopeHuggingFace選擇對應模型下載,這裡以Qwen1.5-14B-Chat為例:

git clone https://www.modelscope.cn/qwen/Qwen1.5-14B-Chat.git

搭建API服務

啟動服務端

單卡部署

CUDA_VISIBLE_DEVICES=0 swift deploy --model_type qwen1half-14b-chat --model_id_or_path /yldm0226/models/Qwen1.5-14B-Chat

CUDA_VISIBLE_DEVICES可以指定使用哪塊GPU進行部署;model_type表示你選擇的模型型別,型別需是SWIFT框架支援的模型種類的一種,可以在此處查詢所有支援的模型;--model_id_or_path表示模型在ModelScope Hub中的model_id或者本地路徑,當指定本地路徑時,程式碼會優先載入本地路徑中的模型權重。

部署成功後,可以看到以下輸出:

INFO:     Started server process [82478]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

多卡部署

RAY_memory_monitor_refresh_ms=0 CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 swift deploy --model_type qwen1half-14b-chat --model_id_or_path /yldm0226/models/Qwen1.5-14B-Chat --tensor_parallel_size 8

同樣的,在部署成功後可以看到以下輸出:

INFO:     Started server process [100001]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

可以透過nvidia-smi命令檢視多卡部署的視訊記憶體佔用情況:

客戶端測試

curl

想要快速測試API的可用性,可以使用curl:

curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen1half-14b-chat",
"messages": [{"role": "user", "content": "請介紹一下API服務"}],
"max_tokens": 1024,
"temperature": 0
}'

model與部署時的model_type一致。

可以得到下面形式的響應:

{"model":"qwen1half-14b-chat","choices":[{"index":0,"message":{"role":"assistant","content":"API(Application Programming Interface,應用程式程式設計介面)服務是一種介面,它允許不同的軟體應用程式之間進行互動和資料共享。API是一組預定義的規則、協議和工具,開發者可以使用它來呼叫或訪問某個應用程式、平臺或服務的功能,而無需瞭解其底層實現細節。簡單來說,它就像一個“橋樑”,使得開發者能夠編寫自己的程式,透過這個介面來獲取資料、執行操作或者觸發特定功能。\n\nAPI服務通常分為以下幾種型別:\n\n1. **Web API**:基於HTTP協議,用於Web應用間的通訊,如RESTful API,它以HTTP請求(GET、POST、PUT、DELETE等)的形式傳送資料。\n\n2. **SDK API**:軟體開發工具包(Software Development Kit)中的API,提供了特定平臺或服務的程式設計介面,如Google Maps API、Facebook API等。\n\n3. **企業級API**:企業內部或外部提供的API,用於內部系統整合,如CRM系統API、支付API等。\n\n4. **機器學習/AI API**:如Google Cloud的機器學習API,允許開發者使用預訓練模型進行預測或處理任務。\n\n5. **API Gateway**:一種服務,它集中管理多個API,提供安全、路由、快取等功能,如AWS API Gateway。\n\n透過API服務,開發者可以快速地擴充套件功能、整合第三方服務,提高開發效率,同時促進了軟體生態系統的繁榮。"},"finish_reason":null}],"usage":{"prompt_tokens":23,"completion_tokens":294,"total_tokens":317},"id":"chatcmpl-f7fa52fbf7de45f1bc1a31e369482a19","object":"chat.completion","created":1709258739}

swift

也可以使用swift框架去編寫客戶端程式碼,下面是一個簡單的示例:

from swift.llm import get_model_list_client, XRequestConfig, inference_client

model_list = get_model_list_client()
model_type = model_list.data[0].id
print(f'model_type: {model_type}')

# 直接輸出
query = '山東的省會在哪裡?'
request_config = XRequestConfig(seed=42)
resp = inference_client(model_type, query, request_config=request_config)
response = resp.choices[0].message.content
print(f'query: {query}')
print(f'response: {response}')

# 流式輸出
history = [(query, response)]
query = '這有什麼好吃的?'
request_config = XRequestConfig(stream=True, seed=42)
stream_resp = inference_client(model_type, query, history, request_config=request_config)
print(f'query: {query}')
print('response: ', end='')
for chunk in stream_resp:
    print(chunk.choices[0].delta.content, end='', flush=True)
print()

第一個問題'山東的省會在哪裡?'使用的是直接返回response的方式,第二個問題'這有什麼好吃的?'使用的是流式輸出的方式,可以根據需要選擇對應的方式。

執行程式,可以得到以下輸出:

query: 山東的省會在哪裡?
response: 山東省的省會是濟南。
query: 這有什麼好吃的?
response: 山東作為中國的一個大省,美食豐富多樣,這裡有許多著名的特色菜餚和小吃。以下是一些你可能會感興趣的:

1. 熱乾麵(不是山東本地的,但濟南也有人喜歡):源於武漢,但在山東也有類似麵食。
2. 魯菜:山東菜系,以濟南菜為代表,如糖醋黃河鯉魚、九轉大腸、蔥燒海參、鍋包肉等,口味偏重,講究原汁原味。
3. 烤鴨:雖然以北京最有名,但山東濟南的烤鴨店也有特色。
4. 鮁魚水餃:山東沿海城市如青島的特色,用新鮮鮁魚做餡,鮮美可口。
5. 豆腐腦:搭配薄餅、香菜、榨菜,是早餐的常見選擇。
6. 煎餅:山東大煎餅,尤其是臨沂煎餅,薄脆可卷各種食材。
7. 油旋:濟南特色小吃,類似油條但更細,酥脆可口。

這只是冰山一角,山東各地還有許多其他美食,如魯西南驢肉火燒、萊陽梨、膠東海鮮等,去山東旅行不妨嘗試一下。

相關文章