一、前言
今天开一篇实用博客,汇总一下工作中将开发好的模型通过不同技术开启Server服务的流程,也是平时工作中需要经常去使用的技术;这里介绍两个实现开启服务的工具——Flask和gRPC,这两个工具的功能还是很强大的,这篇文章也只是介绍一下工程中常用的功能,更多的功能需求,大家可以继续探索;
二、部署UiE模型
2.1 模型介绍
UiE指的是“Universal Information Extraction”,即通用信息抽取。这是一种自然语言处理(NLP)技术,旨在从非结构化的文本数据中自动提取出结构化信息。这些信息可以包括实体名称(如人名、地名)、关系(如人物之间的关系)、事件(如交易、合并)等。通过使用机器学习算法,特别是深度学习模型,UiE能够理解并解析复杂的文本内容;
2.2 模型本地部署
这里使用了github上HUSTAI这位大佬的uie_pytorch这个模型进行本地部署,相关部署细节请参考README;
本地部署好模型时候,本地运行测试一下,如下图所示,我们希望模型从给定的一段文本信息中提取出人名信息,从结果来看,模型不仅识别出了人名,还输出的对应的位置索引以及置信度,模型效果还是非常不错的,接下来我们就要改写模型调用方式,采取web的请求方式来调用该模型;
三、添加模型web服务
3.1 通过Flask启动web服务
3.1.1 安装flask
pip install flask
3.1.2 创建app.py
3.1.2.1 标准模版
假设我们的请求体是一个字典,包含一个键值,为文本信息,那么app.py文件的标准模版如下:
# app.py
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/process', methods=['POST'])
def process():
# 获取请求数据
data = request.json
# 检查请求体是否包含必要的字段
if 'text' not in data:
return jsonify({"error": "Missing required fields"}), 400
text = data['text']
# 这里可以添加你的处理逻辑
result = {
"text": text,
"message": "Data processed successfully"
}
return jsonify(result), 200
if __name__ == '__main__':
app.run(debug=True)
3.1.2.2 模版改写
我们就基于这个模版脚本来生成UiE模型的web服务脚本,具体改写如下:
# app.py
from uie_predictor import UIEPredictor
from flask import Flask, request, jsonify
app = Flask(__name__)
schema = ['人名']
uie = UIEPredictor(model='uie-base', schema=schema)
def main(text_info):
result = uie(text_info)
return result
@app.route('/UIE', methods=['POST'])
def process():
# 获取请求数据
data = request.json
# 检查请求体是否包含必要的字段
if 'text' not in data:
return jsonify({"error": "Missing required fields"}), 400
text = data['text']
model_result = main(text)
# 这里可以添加你的处理逻辑
result = {
"model_result": model_result,
"message": "Data processed successfully"
}
return jsonify(result), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888, debug=True)
3.1.3 启动server服务
3.1.3.1 直接启动
python app.py
3.1.3.2 多副本启动
gunicorn -w 2 -b 0.0.0.0:8888 app:app
3.1.4 创建client.py
3.1.4.1 标准模版
# client.py
import requests
import json
# 定义要发送的数据
data = {
# 请求体数据
}
# 发送 POST 请求
response = requests.post('http://127.0.0.1:5000/process', json=data)
# 打印响应
print(response.status_code)
print(response.json())
3.1.4.2 模版改写
# client.py
import requests
import json
# 定义要发送的数据
data = {
"text": "黄*宝在一次任务中取得了良好的战绩,公司董事长张光明为他颁发了奖章以示鼓励。"
}
# 发送 POST 请求
response = requests.post('http://127.0.0.1:8888/UIE', json=data)
# 打印响应
print(response.status_code)
print(response.json())
3.1.4.3 调用server服务
python client.py
3.2 通过gRPC启动web服务
3.2.1 安装gRPC python包
pip install grpcio grpcio-tools
3.2.2 创建.proto
文件,定义服务接口
// uie_service.proto
syntax = "proto3";
package uie;
// 定义服务
service UIEService {
rpc ProcessText (UITextRequest) returns (UITextResponse) {}
}
// 请求消息
message UITextRequest {
string text = 1;
}
// 响应消息
message UITextResponse {
repeated string results = 1;
string message = 2;
}
3.2.3 生成python脚本服务接口
运行下面指令,生成uie_service_pb2.py
和 uie_service_pb2_grpc.py
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. uie_service.proto
3.2.4 创建服务端文件
创建一个 Python 文件 uie_server.py
,实现服务端逻辑:
# uie_server.py
from uie_predictor import UIEPredictor
import grpc
from concurrent import futures
import time
import uie_service_pb2
import uie_service_pb2_grpc
schema = ['人名']
uie = UIEPredictor(model='uie-base', schema=schema)
class UIEServicer(uie_service_pb2_grpc.UIEServiceServicer):
def ProcessText(self, request, context):
text = request.text
model_result = uie(text)
response = uie_service_pb2.UITextResponse(
results=model_result,
message="Data processed successfully"
)
return response
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
uie_service_pb2_grpc.add_UIEServiceServicer_to_server(UIEServicer(), server)
server.add_insecure_port('[::]:8888')
server.start()
try:
while True:
time.sleep(86400)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
3.2.5 启动服务端
python uie_server.py
3.2.6 创建客户端文件
# uie_client.py
import grpc
import uie_service_pb2
import uie_service_pb2_grpc
def run(text):
channel = grpc.insecure_channel('localhost:8888')
stub = uie_service_pb2_grpc.UIEServiceStub(channel)
response = stub.ProcessText(uie_service_pb2.UITextRequest(text=text))
print("UIE client received:")
print("Results:", response.results)
print("Message:", response.message)
if __name__ == '__main__':
text = "黄*宝在一次任务中取得了良好的战绩,公司董事长张光明为他颁发了奖章以示鼓励。"
run(text)
3.2.7 启动客户端调用
python uie_client.py