在Python中使用gRPC的ML client/server
一个机器学习模型本身是不够的,我们必须部署它来有效地使用它。
假设我们想要做一个微服务来预测房屋定价,这个服务将部署在手机应用程序或web应用程序中,然后我们必须做一个client/server来服务客户端。
在本文中,我们将学习如何制作一个简单的gRPC client/server来响应客户机的请求。
第1步:编写服务:
在我们的例子中,该服务正在预测房屋定价,我已经训练了一个机器学习模型来做到这一点,我将在这个例子中使用它。Python代码如下:
from sklearn.ensemble import RandomForestRegressor from sklearn.externals import joblib def predict_sale_price(MSSubClass, LotArea, YearBuilt, BedroomAbvGr, TotRmsAbvGrd): trained_model = joblib.load('model_backup(RF).joblib') prediction = trained_model.predict([[MSSubClass, LotArea, YearBuilt, BedroomAbvGr, TotRmsAbvGrd]]) return (prediction)
我们使用joblib来加载训练过的机器学习模型。
这个模型有5个输入参数(我们想要预测其销售价格的房子的特征)
第2步:制作Proto文件:
gRPC使用proto而不是Json。ML_example.proto文件如下:
//Define the used version of proto: syntax = 'proto3'; //Define a message to hold the features input by the client : message Features{ float MSSubClass = 1 ; float LotArea = 2 ; float YearBuilt = 3 ; float BedroomAbvGr = 4 ; float TotRmsAbvGrd = 5 ; } //Define a message to hold the predicted price : message Prediction{ float salePrice = 1 ; } //Define the service : service Predict{ rpc predict_sale_price(Features) returns (Prediction){} }
在这里,我们没有给出特征值,这些数字表示序列化特征的顺序。
第3步:为Python生成gRPC类:
打开终端,将目录更改为proto文件所在的文件夹。
要生成gRPC类,我们必须首先安装所需的库:
#Install gRPC :
python -m pip install grpcio
#To install gRPC tools, run:
python -m pip install grpcio-tools googleapis-common-protos
此命令使用ML_example.proto文件生成创建client/server所需的类。
现在,运行以下命令:
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ML_example.proto
生成的文件如下:
ML_example_pb2.py - 包含消息类
- ML_example_pb2.Features 用于输入特征
- ML_example_pb2.Prediction 为预测价格
ML_example_pb2_grpc.py - 包含server和client类
- ML_example_pb2_grpc.PredictServicer 将由server使用
- ML_example_pb2_grpc.PredictStub 将由client使用它
第4步:创建服务器:
服务器将导入生成的文件和将处理预测的函数。
然后我们将定义一个类,它将从客户端获取请求并使用预测函数返回响应。
该请求为我们提供了五个特征,响应是预测。
在此之后,我们将使用之前生成的add_PredictServicer_to_serverfunction (ML_example_pb2_grpc.py)文件向服务器添加PredictSevicer类。
import grpc from concurrent import futures import time # import the generated classes : import ML_example_pb2 import ML_example_pb2_grpc # import the function we made : import predict_sale_price as psp # create a class to define the server functions, derived from # usingSKlearn_pb2_grpc.PredictServicer : class PredictServicer(ML_example_pb2_grpc.PredictServicer): def predict_sale_price(self, request, context): # define the buffer of the response : response = ML_example_pb2.Prediction() # get the value of the response by calling the desired function : response.salePrice = psp.predict_sale_price(request.MSSubClass,request.LotArea, request.YearBuilt, request.BedroomAbvGr, request.TotRmsAbvGrd) return response # creat a grpc server : server = grpc.server(futures.ThreadPoolExecutor(max_workers = 10)) ML_example_pb2_grpc.add_PredictServicer_to_server(PredictServicer(), server) print('Starting server. Listening on port 50051.') server.add_insecure_port('[::]:50051') server.start() try: while True: time.sleep(86400) except KeyboardInterrupt: server.stop(0)
第5步:创建客户端:
在客户端文件中,我们将执行以下操作:
- 打开gRPC channel
- 创建一个stub
- 创建请求消息
- 使用stub 来调用服务
我们生成了一百个房屋特征样本来测试预测函数,我们将生成的样本作为参数传递给预测函数。
我们使用两个计时器来衡量客户端/服务器的性能。
import grpc from random import randint from timeit import default_timer as timer # import the generated classes import ML_example_pb2 import ML_example_pb2_grpc start_ch = timer() # open a gRPC channel channel = grpc.insecure_channel('localhost:50051') # create a stub (client) stub = ML_example_pb2_grpc.PredictStub(channel) end_ch = timer() MSSubClass = [randint(1,11) for i in range(0,1000)] LotArea = [randint(100,1500) for i in range(0,1000)] YearBuilt = [randint(1915,2000) for i in range(0,1000)] BedroomAbvGr = [randint(2,10) for i in range(0,1000)] TotRmsAbvGrd = [randint(2,12) for i in range(0,1000)] ans_lst = [] start = timer() for i in range(0,len(MSSubClass)-1): # create a valid request message requestPrediction = ML_example_pb2.Features(MSSubClass = MSSubClass[i], LotArea = LotArea[i], YearBuilt = YearBuilt[i], BedroomAbvGr = BedroomAbvGr[i], TotRmsAbvGrd = TotRmsAbvGrd[i]) # make the call responsePrediction = stub.predict_sale_price(requestPrediction) ans_lst.append(responsePrediction.salePrice) #print('The prediction is :',responsePrediction.salePrice) print('Done!') end = timer() all_time = end - start ch_time = end_ch - start_ch print ('Time spent for {} predictions is {}'.format(len(MSSubClass),(all_time))) print('In average, {} second for each prediction'.format(all_time/len(MSSubClass))) print('That means you can do {} predictions in one second'.format(int(1/(all_time/len(MSSubClass))))) print('Time for connecting to server = {}'.format(ch_time))
现在是时候尝试我们的客户端/服务器了
首先,将所有需要的文件放在一个目录中,例如:
现在运行服务器:
之后,在另一个终端窗口中,运行客户端:
现在,在我们学习了如何制作client/server之后,我们可以部署我们制作的任何机器学习(ML)模型,我们可以制作服务器并在手机应用程序或Web应用程序中使用它。