ChatGPT平替-?ChatGLM多用戶并行訪問(wèn)部署過(guò)程
ChatGLM對(duì)話模型基本環(huán)境配置和部署請(qǐng)參考上一篇博文《ChatGPT平替-ChatGLM環(huán)境搭建與部署運(yùn)行》,地址為“http://www.dbjr.com.cn/article/283295.htm”。但是,默認(rèn)部署程序僅支持單用戶訪問(wèn),多用戶則需要排隊(duì)訪問(wèn)。測(cè)試過(guò)相關(guān)的幾個(gè)Github多用戶工程,但是其中一些仍然不滿足要求。本節(jié)將系統(tǒng)介紹如何實(shí)現(xiàn)多用戶同時(shí)訪問(wèn)ChatGLM的部署接口,包括http、websocket(流式輸出,stream)和web頁(yè)面等方式,主要目錄如下所示。
(1)api.py http多用戶并行
(2)api.py websocket多用戶并行(流式輸出,stream)
(3)web_demo.py多用戶并行
本節(jié)所涉及程序可根據(jù)文中描述自行編寫(xiě)或替換,也可在“https://download.csdn.net/download/suiyingy/87742178”進(jìn)行下載,文中所有程序均在其中。
1 api.py http多用戶并行
1.1 fastapi并行
ChatGLM-6B工程的api.py是基于fastapi編寫(xiě)的http post服務(wù)程序。具體介紹及調(diào)用方式請(qǐng)參考上一篇博文。運(yùn)行程序后,當(dāng)多用戶同時(shí)調(diào)用該http接口時(shí),程序需要排隊(duì)執(zhí)行,即當(dāng)前用戶指令需要等待上一用戶獲取結(jié)果完成之后才進(jìn)行執(zhí)行。
實(shí)現(xiàn)接口并行的關(guān)鍵在于去除create_item的async,相應(yīng)程序如下所示,該函數(shù)段由RdFast小程序自動(dòng)生成。我們可以根據(jù)如下描述編寫(xiě)程序,也可前往“https://download.csdn.net/download/suiyingy/87742178”進(jìn)行下載,對(duì)應(yīng)下載后的api_http_one_worker.py文件。
#該函數(shù)段由RdFast小程序自動(dòng)生成 from pydantic import BaseModel class User(BaseModel): prompt: str history: list @app.post("/http/noasync") def create_item(request: User): global model, tokenizer json_post_raw = request.dict() json_post = json.dumps(json_post_raw) json_post_list = json.loads(json_post) prompt = json_post_list.get('prompt') history = json_post_list.get('history') max_length = json_post_list.get('max_length') top_p = json_post_list.get('top_p') temperature = json_post_list.get('temperature') response, history = model.chat(tokenizer, prompt, history=history, max_length=max_length if max_length else 2048, top_p=top_p if top_p else 0.7, temperature=temperature if temperature else 0.95) now = datetime.datetime.now() time = now.strftime("%Y-%m-%d %H:%M:%S") answer = { "response": response, "history": history, "status": 200, "time": time } log = "[" + time + "] " + '", prompt:"' + prompt + '", response:"' + repr(response) + '"' print(log) torch_gc()
我們通過(guò)輸入“你好”來(lái)進(jìn)行測(cè)試,并模擬三個(gè)用戶進(jìn)行同時(shí)訪問(wèn)。修改之前三個(gè)用戶獲取返回結(jié)果所需時(shí)間分別為2.08s、4.05s和6.02s,而修改之后獲取結(jié)果所需時(shí)間分別為6.73s、6.78和6.88s。修改前程序順序執(zhí)行,最后一個(gè)用戶獲取結(jié)果所需時(shí)間為6.02s。修改后程序是并行執(zhí)行的,三個(gè)用戶幾乎同時(shí)獲得訪問(wèn)結(jié)果。
由于模型參數(shù)在多個(gè)線程之間是共享的,且多線程狀態(tài)下程序會(huì)交替運(yùn)行,因此多線程狀態(tài)下獲取結(jié)果的總時(shí)間反而增加了。因此,這種修改并不適合http模式,比較適合于websocket流式輸出。模擬多用戶調(diào)用的測(cè)試程序如下所示。
import json import time import requests import threading def get_ans(id, prompt): t0 = time.time() headers = {'Content-Type': 'application/json'} url = 'http://IP:Port/http/noasync' data = {'prompt': prompt, 'history': []} data = json.dumps(data) reponse = requests.post(url=url, data=data, headers=headers) print(id, '耗時(shí)為:', round(time.time() - t0, 2), 's,結(jié)果為:', reponse .text) if __name__ == '__main__': t1 = threading.Thread(target=get_ans, args=('線程1', '你好')) t2 = threading.Thread(target=get_ans, args=('線程2', '你好')) t3 = threading.Thread(target=get_ans, args=('線程3', '你好')) t1.start() t2.start() t3.start()
1.2 fastapi多線程并行
fastapi多線程通過(guò)啟動(dòng)參數(shù)workers來(lái)進(jìn)行控制。如果程序直接將api.py中的workers設(shè)置為大于1的數(shù)值,即“uvicorn.run(app, host='0.0.0.0', port=8000, workers=2)”,那么會(huì)報(bào)錯(cuò)“WARNING: You must pass the application as an import string to enable 'reload' or 'workers'.”,報(bào)錯(cuò)后程序退出并停止執(zhí)行。正確修改為“uvicorn.run('api:app', host='0.0.0.0', port=8000, workers=2)”,其中api表示當(dāng)前python文件名稱。
這相當(dāng)于各個(gè)線程分別運(yùn)行api.py文件的app,運(yùn)行次數(shù)由workers決定。從這里可以看到,程序并不能識(shí)別’__main__’函數(shù)中的變量,因此要把模型定義放在全局位置,如下所示,否則會(huì)報(bào)錯(cuò)誤“NameError: name 'model' is not defined”。
app = FastAPI() tokenizer = AutoTokenizer.from_pretrained("chatglm-6b-int4-qe", trust_remote_code=True) model = AutoModel.from_pretrained("chatglm-6b-int4-qe", trust_remote_code=True).half().cuda() model.eval()
在多線程情況下,類似上一節(jié),無(wú)論是否使用asnc,程序運(yùn)行時(shí)間基本一致。但是,基本顯存會(huì)隨著線程數(shù)量增多而增加。實(shí)際運(yùn)行時(shí),單個(gè)線程應(yīng)需要10GB左右顯存,包括模型加載和推理。各個(gè)線程數(shù)量下的模型加載顯存如下所示。而1.1節(jié)的方法中單個(gè)線程僅需要3939MB。
Workers=1, 7329MB
Workers=2, 17875MB
Workers=3, 24843MB
Workers=4, 31811MB
Workers=5, 38779MB
我們可以根據(jù)上述描述編寫(xiě)程序,也可前往“https://download.csdn.net/download/suiyingy/87742178”進(jìn)行下載,對(duì)應(yīng)下載后的api_http_three_worker.py文件。
2 api.py websocket多用戶并行
Fastapi websocket的創(chuàng)建方法如下所示,該示例程序來(lái)源于RdFast小程序自動(dòng)生成。
#該示例程序來(lái)源于RdFast小程序自動(dòng)生成。 from fastapi import FastAPI, WebSocket, WebSocketDisconnect app = FastAPI() connected_websockets = {} @app.websocket("/ws/{client_id}") async def websocket_endpoint(websocket: WebSocket, client_id: str): await websocket.accept() connected_websockets[client_id] = websocket try: while True: # 接收客戶端websocket發(fā)送過(guò)來(lái)的信息 data = await websocket.receive_text() # 將接收到的信息通過(guò)所有已連接的websocket廣播給其他客戶端 for ws in connected_websockets.values(): await ws.send_text(f"Client {client_id}: {data}") except WebSocketDisconnect: # 連接斷開(kāi)時(shí),從已連接的客戶端中移除 del connected_websockets[client_id]
將上述程序與ChatGLM結(jié)合即可實(shí)現(xiàn)ChatGLM的websocket api接口。示例程序如下所示:
@app.websocket("/ws/{client_id}") async def websocket_endpoint(ws: WebSocket, client_id: str): await ws.accept() print('已連接') try: while True: # 接收客戶端websocket發(fā)送過(guò)來(lái)的信息 data = await ws.receive_text() print('收到消息:', data) resp0 = '' for response, history in model.stream_chat(tokenizer, data, [], max_length= 2048,top_p= 0.7, temperature= 0.95): print('response:', response) res = response.replace(resp0, '') resp0 = response await ws.send_text(res) await ws.send_text('<rdfast stop>')#自定義結(jié)束符 except WebSocketDisconnect: print('連接已斷開(kāi)')
我們可以根據(jù)上述描述編寫(xiě)程序,也可前往“https://download.csdn.net/download/suiyingy/87742178”進(jìn)行下載,對(duì)應(yīng)下載后的api_http_one_worker.py文件。Websocket測(cè)試程序如下所示。
from websocket import create_connection def connect_node(ques): ans = '' url = "ws://IP:Port/ws/2" ws = create_connection(url) ws.send(ques) while True: try: recv_text = ws.recv() print(recv_text) if '<rdfast stop>' in recv_text: print('break') break ans += recv_text except Exception as e: print('except: ', str(e)) recv_text = ws.recv() break print(ans) ws.close() connect_node('你好')
類似http接口,使用async時(shí)多用戶調(diào)用websocket將排隊(duì)獲取結(jié)果。此時(shí),程序去除async之后無(wú)法獲取結(jié)果。使用1.2中多線程啟動(dòng)方式則可以實(shí)現(xiàn)多用戶同時(shí)獲得結(jié)果,程序基本一致,也可參考“https://download.csdn.net/download/suiyingy/87742178”的api_http_three_worker.py。
另外,不同的python包所支持的工作方式不同。例如,websocket-server支持多用戶同時(shí)調(diào)用websocket接口,安裝方式為“pip install websocket-server”。運(yùn)行程序時(shí)可能會(huì)出現(xiàn)錯(cuò)誤提示“KeyError: 'upgrade'”,但這不影響結(jié)果獲取。websocket-server ChatGLM相應(yīng)程序見(jiàn)“https://download.csdn.net/download/suiyingy/87742178”的api_ws.py程序。
3 web_demo.py多用戶并行
Web_demo.py默認(rèn)狀態(tài)下多用戶會(huì)排隊(duì)訪問(wèn),使用下面命令啟動(dòng)時(shí)可同時(shí)獲取結(jié)果。concurrency_count表示最多可同時(shí)獲取結(jié)果的用戶數(shù),即并發(fā)數(shù)。max_size表示排隊(duì)的數(shù)量,即最多允許多少個(gè)用戶處于排隊(duì)狀態(tài)。使用時(shí)只需將web_demo.py的最后一行替換成如下啟動(dòng)方式即可。Web_demo2.py采用streamlit實(shí)現(xiàn),默認(rèn)支持多用戶同時(shí)訪問(wèn)。
demo.queue( concurrency_count=5, max_size=500).launch(share=False, inbrowser=True, server_name="0.0.0.0", server_port=8000)
到此這篇關(guān)于ChatGPT平替- ChatGLM多用戶并行訪問(wèn)部署的文章就介紹到這了,更多相關(guān)ChatGPT平替ChatGLM部署內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- linux環(huán)境部署清華大學(xué)大模型最新版 chatglm2-6b 圖文教程
- macbook安裝環(huán)境chatglm2-6b的詳細(xì)過(guò)程
- ChatGLM-6B+LangChain環(huán)境部署與使用實(shí)戰(zhàn)
- 基于本地知識(shí)的問(wèn)答機(jī)器人langchain-ChatGLM 大語(yǔ)言模型實(shí)現(xiàn)方法詳解
- ChatGPT平替-ChatGLM環(huán)境搭建與部署運(yùn)行效果
- ChatGLM?集成LangChain工具詳解
- 基于prompt?tuning?v2訓(xùn)練好一個(gè)垂直領(lǐng)域的chatglm-6b
- 最簡(jiǎn)化ChatGLM2-6b小白部署教程【windows系統(tǒng),16G內(nèi)存即可,對(duì)顯卡無(wú)要求,CPU運(yùn)行】
相關(guān)文章
hadoop遷移數(shù)據(jù)應(yīng)用實(shí)例詳解
這篇文章主要介紹了hadoop遷移數(shù)據(jù)應(yīng)用實(shí)例,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06大數(shù)據(jù)HelloWorld-Flink實(shí)現(xiàn)WordCount
這篇文章主要介紹了大數(shù)據(jù)HelloWorld-Flink實(shí)現(xiàn)WordCount的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08偽靜態(tài)技術(shù)介紹與優(yōu)缺點(diǎn)分析(較完整篇)
偽靜態(tài)太適合用在普通的企業(yè)網(wǎng)站上了——既不要求高并發(fā),但同時(shí)又很在乎seo(搜索引擎優(yōu)化),而且也要求后臺(tái)可動(dòng)態(tài)更新。2009-11-11Runnable.com 在線測(cè)試代碼片分享網(wǎng)站
Runnable是一個(gè)一站式的代碼片段集合網(wǎng)站,你不僅可以搜索代碼,還可以編輯、運(yùn)行這些代碼片段,以確保它們的正確性與可用性2013-12-12