在日常中我们通常会对我们已经做好的端对端对机器学习或者深度学习项目,部署到网页端或者GPU服务器中,具体的模型工程部署的方法有几种,如下:
这里我只介绍第一个,将模型打包成api接口这一种方法
将模型打包成api接口通常需要借助一些web框架,最常用的就是flask框架。
我们部署的方式,就是将模型打包成一个http地址,当我们要去访问这个地址时,我们通过http协议向服务器传递一个request对象,这个request对象就包含了的请求参数,以及请求方式。当模型拿到这个request,就开始模型eval,最后返回请求的结果,通常request返回的结果格式为json。
其中flask request请求方式分为两种POST和GET。
最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。
在Flask的官方文档中是这样介绍request的:对于 Web 应用,与客户端发送给服务器的数据交互至关重要。在 Flask 中由全局的 request 对象来提供这些信息。
从Flask模块导入request:from flask import request
这里以一个示例来以此介绍request属性
from flask import Flask,request
app=Flask(__name__)
@app.route('/login', methods = ['GET','POST'])
def login():
if request.method == 'POST':
if request.form['username'] == request.form['password']:
return 'TRUE'
else:
#当form中的两个字段内容不一致时,返回我们所需要的测试信息
return str(request.headers) #需要替换的部分
else:
return render_template('login.html')
return request.method #POST
return json.dumps(request.form)
#{"username": "123", "password": "1234"}
return json.dumps(request.args)
#url:http://192.168.1.183:5000/login?a=1&b=2、返回值:{"a": "1", "b": "2"}
print(request.args['a'])
#输出:1
return str(request.values)
#CombinedMultiDict([ImmutableMultiDict([('a', '1'), ('b', '2')]), ImmutableMultiDict([('username', '123'), ('password', '1234')])])
return str(request.headers) #headers信息
request.headers.get('User-Agent') #获取User-Agent信息
return 'url: %s , script_root: %s , path: %s , base_url: %s , url_root : %s' % (request.url,request.script_root, request.path,request.base_url,request.url_root)
'''
url: http://192.168.1.183:5000/testrequest?a&b ,
script_root: ,
path: /testrequest ,
base_url: http://192.168.1.183:5000/testrequest ,
url_root : http://192.168.1.183:5000/
'''
@app.route('/upload',methods=['GET','POST'])
def upload():
if request.method == 'POST':
f = request.files['file']
filename = secure_filename(f.filename)
#f.save(os.path.join('app/static',filename))
f.save('app/static/'+str(filename))
return 'ok'
else:
return render_template('upload.html')
#html
<!DOCTYPE html>
<html>
<body>
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" /><br />
<input type="submit" value="Upload" />
</form>
</body>
</html>
其中POST与GET区别:
请求方式 | request.args | request.form | request.values |
---|---|---|---|
POST | ☑️ | ☑️ | |
GET | ☑️ | ☑️ |
GET请求方式
get请求的数据是放在QuerySting中的request.args封装的就是get请求的数据 类型为字典
示例:
获取name的值:
request.args["name"]
request.args.get("name")
request.args.getlist("name_list")
@app.route('/form_do')
def form_do():
uname = request.args.get('uname')
upwd = request.args.get('upwd')
print()
return '用户名称:%s,用户密码:%s' % (uname,upwd)
POST请求方式
post请求的数据是放在 form中的request.form封装的就是POST请求的数据 类型为字典
示例:
获取name的值:
request.form["name"]
request.form.get("name")
request.form.getlist("name_list")
@app.route('/post_do',methods=['POST'])
def post_do():
uname=request.form.get('uname')
upwd = request.form.get('upwd')
uemail = request.form.get('uemail')
trueName = request.form.get('trueName')
return "姓名:%s,密码:%s,邮件:%s,真实姓名:%s" % (uname,upwd,uemail,trueName)
最后需要知道的是return的返回的值必须为json格式,可以使用函数如下函数进行格式转换
up主做的都是与计算机视觉有关的,所以传人的参数通常为一个图片,也就是request.files,但是request.files传入的文件参数,不能直接被深度学习模型使用需要转换。
这里实例用到模型是yolov5,通过torch在github下载获取
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
from flask import Flask,request,jsonify
app=Flask(__name__)
@app.route('/predict',methods=["GET","POST"])
def predict():
if not request.method == "POST":
return
if request.files.get("image"):
image_file = request.files["image"]
print(image_file)
image_bytes = image_file.read()
img = Image.open(io.BytesIO(image_bytes))
results=model(img)
return jsonify(results)
app.run(host="127.0.0.1",port=5005)
curl -X POST -F image=@1.jpg http://127.0.0.1:5005/predict
详细的curl命令可以参考下面这个链接
http://www.ruanyifeng.com/blog/2019/09/curl-reference.html