大佬教导我rpc比http更底层,效率更高,这是个大坑,用处也很多,暂时粘下使用方法,留待再研究:
grpc会生成一套两个python类给客户端和服务端使用,首先生成下:
编写文件qa.proto:
syntax = "proto3";
message QaRequest {
string character=1;
string query=2;
string model_path=3;
}
message QaResponse {
string answer=1;
string qa_flag=2;
double score=3;
}
//message QaResponse {
// repeated QaItem recommends=1;
//}
service QaRecommend {
rpc qa_recommend(QaRequest) returns(QaResponse) {}
}
然后执行命令生成:
pip install grpcio
pip install grpcio-tools
python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. qa.proto
服务端:
# -*- coding: UTF-8 -*-
from concurrent import futures
import time
import grpc
import qa_pb2
import qa_pb2_grpc
from functools import lru_cache
from LRUCache import LRUCache
import subprocess
import os
from fire import Fire
cache = LRUCache(6)
#@lru_cache(maxsize=2)
def getModel(model_path):
return model
class QaRecommend(qa_pb2_grpc.QaRecommendServicer):
# 实现 proto 文件中定义的 rpc 调用
def qa_recommend(self, request, context):
character = request.character
query = request.query
model_path = request.model_path
print(f"model:{character},query:{query},model_path:{model_path}")
model = getModel(model_path)
print(f"model:{character},query:{query}")
res = model.inference_query(query)
answer = res[0]
score = res[1]
answer = str(answer).replace("[player,1]","君")
print(f"answer:{answer}\nscore:{score}")
return qa_pb2.QaResponse(answer=answer,score=score,qa_flag="0")
def serve():
# 启动 rpc 服务
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
qa_pb2_grpc.add_QaRecommendServicer_to_server(QaRecommend(), server)
server.add_insecure_port('127.0.0.1:18888')
server.start()
print("server started")
try:
while True:
time.sleep(60*60*24) # one day in seconds
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
客户端:
with grpc.insecure_channel('127.0.0.1:18888') as channel:
stub = qa_pb2_grpc.QaRecommendStub(channel)
#ret = qa_recommend(stub, character, query,i)
ret = stub.qa_recommend(qa_pb2.QaRequest(character=character,query=query,model_path=i))