在一些算法团队中,有些内部产品会将数据获取,ETL,模型开发,部署,DevOps整合成一套工具栈,使得算法同学能够专注算法开发与优化。博主观察到现在存在一些开源的产品,比如BentoML,可以体现类似的思想。但是有些较早期的团队,没有这样的工具栈,就需要手动推进流程。这里讨论一些基于Python的常见的模型部署流程,但是博主同样见到过用Python做模型开发语言,用C++和Go做模型部署语言的,早期做CV的时候,多是基于C++,近期也看到过基于Go做本地模型部署的。

基于Flask的方式(配合gunicorn)

from flask import Flask

app = Flask(__name__)


@app.route('/ner', methods=['GET'])
def ner():
    return "NER service."

@app.route('/pos', methods=['GET'])
def pos():
    return "POS service."

if __name__ == "__main__":
    app.debug = False
    app.run()

4.jpg

如果改用gunicorn启动服务呢?

2.jpg

基于wsgiref的方式

from wsgiref.simple_server import make_server
def ner(environ, start_response):
    #必须
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [("NER service.").encode("utf-8")]#编码

if __name__ == "__main__":
    server = make_server("127.0.0.1", 5000, ner)
    #只接受一次请求
    #server.handle_request() 
    #接受无限次请求
    server.serve_forever()

3.jpg

这种实现无法用gunicorn启动服务。

基于falcon的方式(配合gunicorn)

能否基于falcon实现呢?

service.py

import falcon

class NER():    
    def on_get(self, req, resp):
        resp.body = '{"message":"NER service"}'
        resp.status = falcon.HTTP_200

class POS():    
    def on_get(self, req, resp):
        resp.body = '{"message":"POS service"}'
        resp.status = falcon.HTTP_200

run.py

import falcon
import service#引用上述方式

api = application = falcon.API()
ner = service.NER()
pos = service.POS()

api.add_route('/ner', ner)
api.add_route('/pos', pos)

1.jpg

对比三种方式,第三种可能实用性较优。优点如下:(1)实现多服务部署(基于Flask的方式同样支持)(2)合理发挥gunicorn的易用性(进程,端口和IP地址设定等)(3)代码实现的整体结构较清晰,易管理

补充: 1.算法服务部署