文章目錄
- 背景
- 操作流程
- 開源模型選擇
- 算力服務器平臺開通
- 部署一個算力服務器
- 登錄GPU算力服務器進行模型的部署
- FastDeploy 快速部署服務
- 安裝paddlepaddle-gpu
- 1. 降級沖突的庫版本
- 安裝fastdeploy
- 直接部署模型(此處大約花費15分鐘時間)
- 放行服務端口供公網訪問
- 最后一個錯誤,馬上部署成功
- 1. 手動配置 `/etc/hosts` 文件
- 調用大模型服務
- 官方demo調用
- 文字交互demo
- 文+圖+連續對話版本(python代碼)
- openai的接口調用方式
- 總結
背景
文心大模型全面開源!
作為備受關注的文心大模型,歷經發展與積淀,如今迎來重要一步——全面開源并免費開放下載體驗!
我們相信,開放協作、集思廣益,是推動大模型技術長遠發展和釋放其真正價值的關鍵。此次開源,正是邁出了堅實的一步。
我親身體驗后,整體感受超出預期!現將詳細的體驗流程整理如下,供大家參考:
操作流程
開源模型選擇
今天搞這個模型:
ERNIE-4.5-VL-28B-A3B-PT
ERNIE-4.5-VL-28B-A3B 是一個多模態 MoE 聊天模型,擁有 28B 總參數和每個標記激活的 3B 參數。
操作文檔在這里:
https://gitcode.com/paddlepaddle/ERNIE-4.5-VL-28B-A3B-PT
咱們使用單卡部署,至少需要80G的內存,咱們直接使用A100,那么哪里可以搞到物美價廉的A100呢?
算力服務器平臺開通
經過我的多方折騰,發現有個地方還是很不錯的,推薦給大家:
猛戳這里!——優云智算
沒錯,就是這個平臺,上去實名認證之后,就可以獲得10元券,然后就可以跑咱們這次要搞的文心一言的開源大模型ERNIE-4.5-VL-28B-A3B-PT 啦
部署一個算力服務器
在優云智算平臺上,點擊部署GPU實例,選擇平臺鏡像,然后選擇pytorch + ubutu ,然后在實例配置中的更多型號里,選擇A100,我們選擇豪華的A100(正好80G顯存)來跑今天的模型,具體的配置參照下圖,PyTouch的相關版本選擇如下,大家別搞錯了
在實例配置中,選擇A100。
然后點擊立即部署即可(這里我們選擇按量計費,該計費類型支持關機不收費,磁盤、鏡像關機正常計費)這種方式更友好一些,有事了就先關機,回來了就開機繼續搞,這里的10元代金券可以直接抵扣,只要操作不失誤應該是夠用的,如果對自己沒信心,也別擔心,這是后付費的,在系統給出回收的提示之前付清費用,服務器都是會保留的。(一般只留24小時)
選好之后,點擊立即部署,服務器就會將相應的環境部署好。
這里的狀態變為已運行的時候,就說明已經部署好了,就可以進行登錄使用了。
現在已經是運行中了,代表服務器環境已經部署好了!
登錄GPU算力服務器進行模型的部署
咱們點擊登錄,進入到這個服務器中開始部署模型(或者直接復制相應的ssh代碼和密碼,自己進入終端或者其他工具中進行登錄都可以)。
復制這里的密碼,然后進行遠程登錄
登陸成功之后界面如下:
FastDeploy 快速部署服務
咱們這次主要使用官方推薦的FastDeploy 快速部署服務
其中用到了 FastDeploy 快速部署服務,
https://github.com/PaddlePaddle/FastDeploy
咱們這次用的A100的部署,詳細部署信息可以查看:
https://github.com/PaddlePaddle/FastDeploy/blob/develop/docs/get_started/installation/nvidia_gpu.md
如果不想看文檔嫌麻煩的,也可以直接按照本文進行操作即可。
咱們本次實際的操作步驟總結如下圖:
安裝paddlepaddle-gpu
1.先運行安裝 paddlepaddle-gpu(此處大約花費15分鐘時間)
python -m pip install paddlepaddle-gpu==3.1.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/
這里安裝完畢會報錯,
這是因為:
- 版本不匹配:PyTorch 2.4.0+cu124 明確要求特定版本的 CUDA 工具鏈(如 nvidia-cublas-cu1212.4.2.65、nvidia-cudnn-cu129.1.0.70 等),但你的環境中安裝的是更新的版本(如 12.6.4.1、9.5.1.17 等)。
- 依賴解析限制:pip 的依賴解析器在安裝時可能未考慮所有已安裝包的兼容性,導致不兼容的版本被安裝。
然后進行解決
1. 降級沖突的庫版本
根據 PyTorch 的要求,手動降級所有 CUDA 相關庫至指定版本:
pip install nvidia-cublas-cu12==12.4.2.65 \nvidia-cuda-cupti-cu12==12.4.99 \nvidia-cuda-nvrtc-cu12==12.4.99 \nvidia-cuda-runtime-cu12==12.4.99 \nvidia-cudnn-cu12==9.1.0.70 \nvidia-cufft-cu12==11.2.0.44 \nvidia-curand-cu12==10.3.5.119 \nvidia-cusolver-cu12==11.6.0.99 \nvidia-cusparse-cu12==12.3.0.142 \nvidia-nccl-cu12==2.20.5 \nvidia-nvjitlink-cu12==12.4.99 \nvidia-nvtx-cu12==12.4.99 \triton==3.0.0
解決完畢后驗證環境:
import torch
print(torch.__version__) # 輸出: 2.4.0+cu124
print(torch.cuda.is_available()) # 應輸出 True
安裝fastdeploy
此處花費時間不超過1分鐘。
注意,此處咱們只安裝這個 stable release即可,不用按照教程安裝latest Nightly build
python -m pip install fastdeploy-gpu -i https://www.paddlepaddle.org.cn/packages/stable/fastdeploy-gpu-80_90/ --extra-index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
這是安裝完畢的圖片,看起來好像有一些報錯,咱們先不管,繼續往下執行即可。
直接部署模型(此處大約花費15分鐘時間)
python -m fastdeploy.entrypoints.openai.api_server \--model baidu/ERNIE-4.5-VL-28B-A3B-Paddle \--port 8180 \--metrics-port 8181 \--engine-worker-queue-port 8182 \--max-model-len 32768 \--enable-mm \--reasoning-parser ernie-45-vl \--max-num-seqs 32
報錯了
報錯的原因顯示:
表明 Python 在嘗試加載 PaddlePaddle 的核心庫時,找不到 GCC 的 OpenMP 運行時庫。
既然缺失了,那咱們馬上就安裝,安排,解決!
執行以下代碼進行解決:
apt-get update
apt-get install -y libgomp1
解決完畢之后,繼續執行部署模型:
可以看到,已經開始部署了,說明環境已經正常了,等待模型部署完畢,我們進行調用即可。
放行服務端口供公網訪問
此處需要將8180的端口在防火墻放行,這樣在公網才能訪問我們部署好的模型:
在云服務器實例的操作頁面,選擇更多操作——配置防火墻,然后在其中放行 8180端口。
點擊編輯防火墻規則:
點擊添加規則,然后填寫相應的信息:
放行成功后效果如下
最后一個錯誤,馬上部署成功
模型部署完了,但是最后果然又報錯了:
這個錯誤是由于系統無法解析主機名(hostname)對應的 IP 地址導致的,具體來說,這行代碼嘗試通過主機名獲取 IP 地址時失敗了(錯誤 [Errno -2] Name or service not known
表示名稱解析失敗)。
解決方案:
1. 手動配置 /etc/hosts
文件
通過修改 /etc/hosts
,將主機名映射到本地 IP(通常是 127.0.0.1
或內網 IP):
步驟:
- 查看當前主機名:bash
hostname
# 假設輸出為:eb1879bc7658(你的容器ID或主機名)
- 編輯
/etc/hosts
文件:bash
vi /etc/hosts
- 在文件中添加一行,將主機名映射到
127.0.0.1
:****
(如果已有 127.0.0.1 localhost
,直接在后面加上主機名即可)
- 保存退出(vi 中按
Esc
,輸入:wq
回車)。
然后又重新跑一下(跑一次大概15分鐘左右)
出現圖中顯示的Uvicorn running on http://0.0.0.0:8180
的時候就代表服務已經部署成功了!咱們現在就將文心一言開源大模型 擁有 28B 總參數的多模態 MoE 聊天模型ERNIE-4.5-VL-28B-A3B 在自己的服務器上部署成功了!
調用大模型服務
接下來可以進行相關的調用來試一下模型的表現了。
官方demo調用
以下是官方給的demo,是讓模型識別一個圖片鏈接,然后輸出圖片描述的。
我改造了一個python調用的版本,代碼如下:
使用python代碼訪問已經部署的模型:
import requests
import json# 定義 API 接口的 URL
url = "http://你的服務器公網IP:8180/v1/chat/completions"# 定義請求頭
headers = {"Content-Type": "application/json"
}# 定義請求體
payload = {"messages": [{"role": "user", "content": [{"type": "image_url", "image_url": {"url": "https://paddlenlp.bj.bcebos.com/datasets/paddlemix/demo_images/example2.jpg"}},{"type": "text", "text": "Descript this image"}]}],"metadata": {"enable_thinking": False}
}# 發送 POST 請求
try:response = requests.post(url, headers=headers, data=json.dumps(payload))# 檢查響應狀態碼response.raise_for_status() # 拋出 HTTPError 異常,如果狀態碼不是 200-299# 解析 JSON 響應response_json = response.json()# 打印響應結果print(json.dumps(response_json, indent=2, ensure_ascii=False)) # 美化輸出,支持中文except requests.exceptions.RequestException as e:print(f"請求發生錯誤: {e}")
except json.JSONDecodeError as e:print(f"JSON 解析錯誤: {e}")
except Exception as e:print(f"發生其他錯誤: {e}")
注意使用的時候把你的服務器公網IP替換進去
可以看到模型已經可以正常返回了。
文字交互demo
接下來,咱們給他發送文字,讓模型進行正常的回復:
代碼如下:
import requests
import json# 定義 API 接口的 URL
url = "http://你的服務器公網IP/v1/chat/completions"# 定義請求頭
headers = {"Content-Type": "application/json"
}# 定義請求體 - 文本聊天
def generate_text_chat_payload(user_message):"""""" """生成文本聊天請求的 payload。Args:user_message: 用戶發送的文本消息 (string)。Returns:一個 Python 字典,代表請求體。"""payload = {"messages": [{"role": "user", "content": user_message}],"metadata": {} # 可以包含其他元數據,比如 {"enable_thinking": False}}return payload# 設置用戶消息
user_message = "你好,你現在是一個人工智能助手。隨便聊一些事情。"# 生成請求體 payload
payload = generate_text_chat_payload(user_message)# 發送 POST 請求
try:response = requests.post(url, headers=headers, data=json.dumps(payload))# 檢查響應狀態碼response.raise_for_status() # 拋出 HTTPError 異常,如果狀態碼不是 200-299# 解析 JSON 響應response_json = response.json()# 打印響應結果print("響應:")print(json.dumps(response_json, indent=2, ensure_ascii=False)) # 美化輸出,支持中文# 提取模型回復內容 (如果 API 響應結構不同,你需要相應地修改這部分)try:model_response = response_json["choices"][0]["message"]["content"]print("\n模型回復:")print(model_response)except (KeyError, IndexError) as e:print(f"\n無法提取模型回復: {e}")except requests.exceptions.RequestException as e:print(f"請求發生錯誤: {e}")
except json.JSONDecodeError as e:print(f"JSON 解析錯誤: {e}")
except Exception as e:print(f"發生其他錯誤: {e}")
文+圖+連續對話版本(python代碼)
好吧,合并在一起,并且可以連續對話的版本應運而生:
import requests
import json
import io
from PIL import Image# 定義 API 接口的 URL
url = "http://你的服務器公網IP:8180/v1/chat/completions"# 請求頭
headers = {"Content-Type": "application/json"
}def display_image_from_url(image_url):"""從 URL 顯示圖片"""try:response = requests.get(image_url, stream=True)response.raise_for_status()img = Image.open(io.BytesIO(response.content))img.show()except requests.exceptions.RequestException as e:print(f"無法從 URL 獲取圖片: {e}")except Exception as e:print(f"顯示圖片時發生錯誤: {e}")def generate_chat_payload(messages, metadata={}):"""生成聊天請求的 payload。Args:messages (list): 包含對話消息的列表,每個消息是一個字典。metadata (dict, optional): 元數據字典。 默認為 {}.Returns:dict: 聊天請求的 payload。"""payload = {"messages": messages,"metadata": metadata # 可以添加 enable_thinking: False 等}return payloadconversation_history = []def main():global conversation_historywhile True:user_input_type = input("請輸入 (1: 文字, 2: 圖片URL): ")if user_input_type == "1":user_text = input("請輸入文字: ")user_message = {"role": "user", "content": user_text}elif user_input_type == "2":image_url = input("請輸入圖片 URL: ")user_message = {"role": "user","content": [{"type": "image_url", "image_url": {"url": image_url}},{"type": "text", "text": "請描述這張圖片"} # 提示模型描述]}else:print("無效的輸入類型。")continueconversation_history.append(user_message)payload = generate_chat_payload(conversation_history)try:response = requests.post(url, headers=headers, data=json.dumps(payload))response.raise_for_status()response_json = response.json()# print("\nAPI 響應:")# print(json.dumps(response_json, indent=2, ensure_ascii=False))if "choices" in response_json and response_json["choices"]:model_response = response_json["choices"][0]["message"]conversation_history.append(model_response)print("\n模型回復:")if isinstance(model_response["content"], str):print(model_response["content"])elif isinstance(model_response["content"], list):for item in model_response["content"]:if item["type"] == "text":print(item["text"])elif item["type"] == "image_url":print("顯示圖片...")display_image_from_url(item["image_url"]["url"])else:print("無法處理的模型回復內容類型")else:print("\n沒有從模型收到回復。")except requests.exceptions.RequestException as e:print(f"請求發生錯誤: {e}")except json.JSONDecodeError as e:print(f"JSON 解析錯誤: {e}")except (KeyError, IndexError) as e:print(f"從響應中提取信息時出錯: {e}")except Exception as e:print(f"發生其他錯誤: {e}")continue_chat = input("繼續對話? (y/n): ")if continue_chat.lower() != "y":breakif __name__ == "__main__":main()
openai的接口調用方式
當然,咱們這種部署方式同樣也兼容openai的接口調用方式,如:
import openai
host = "117.50.192.15"
port = "8180"
client = openai.Client(base_url=f"http://{host}:{port}/v1", api_key="null")response = client.chat.completions.create(model="null",messages=[{"role": "system", "content": "I'm a helpful AI assistant."},{"role": "user", "content": "給我寫一首關于愛情的詩"},],stream=True,
)
for chunk in response:if chunk.choices[0].delta:print(chunk.choices[0].delta.content, end='')
print('\n')
這就提供了很多思路,可以直接把這個接口對接到dify等工具上,然后打造自己的專屬工作流,知識庫等,這絕不亞于市面上的那些大模型。
并且如果感覺回復的內容不是很符合自己的要求,還可以針對模型進行微調,比其他非開源只能調用api-key的模型想象空間大了很多!!!
總結
本文詳細介紹了如何使用FastDeploy快速部署大模型服務的全過程,涵蓋了從選擇開源模型到在GPU算力服務器上完成部署并開放公網訪問的各個步驟。首先,我們回顧了相關的背景信息,并介紹了操作流程。接著,文章通過具體的部署實例,逐步展示了如何解決可能出現的庫版本沖突問題、安裝必要的軟件包以及如何配置系統文件(如/etc/hosts)來確保模型服務的順利運行。
通過使用FastDeploy,用戶能夠更加高效地部署大規模機器學習模型,并能夠方便地進行文字、圖像及連續對話版本的交互測試。此外,文章還分享了官方demo和openai接口的調用方式,幫助讀者更好地理解和應用模型服務。
本文不僅為讀者提供了清晰的操作指南,還解決了在模型部署過程中常見的技術難題,使讀者能夠輕松搭建和使用高效的AI服務。
文心大模型的開源標志著技術權力從巨頭壟斷向全民共創的轉移。然而,開源的本質不是慈善,而是通過開放降低生態摩擦,讓創新在自由流動中爆發更大價值。
一起來輕松玩轉文心大模型吧——文心大模型免費下載地址:
https://ai.gitcode.com/theme/1939325484087291906