如何提高将图像发布到 Rest 时的传输速度 API
How to increase transfer speed when POSTing an image to a Rest API
我不熟悉开发 Rest APIs 并尝试使用 Python 和 Rest APIs 部署机器学习模型进行图像分割。
在服务器端我使用 FastAPI 而在客户端我使用 Python 请求库。客户端已经将图像大小调整为模型的必要输入大小,因此不会发送不必要的大图像。服务器将接收到的图像提供给模型和 returns 二进制分割掩码。图像和蒙版从 numpy 数组转换为列表,然后作为 json 数据发送。
下面是一些代码,代表我刚才描述的内容。由于我无法在此处提供模型,因此这个最小可重现示例中的服务器将 return 接收到的相同图像。
server.py
import uvicorn
from fastapi import FastAPI
import numpy as np
from datetime import datetime
app = FastAPI()
@app.get('/test')
def predict_and_process(data: dict = None):
start = datetime.now()
if data:
image = np.asarray(data['image'])
print("Time to run: ", datetime.now() - start)
return {'prediction': np.squeeze(image).tolist()}
else:
return {'msg': "Model or data not available"}
def run():
PORT = 27010
uvicorn.run(
app,
host="127.0.0.1",
port=PORT,
)
if __name__=='__main__':
run()
client.py
import requests
import numpy as np
import json
from matplotlib.pyplot import imread
from skimage.transform import resize
from datetime import datetime
def test_speed():
path_to_img = r"path_to_some_image"
image = imread(path_to_img)
image = resize(image, (1024, 1024))
img_list = image.tolist()
data = {'image': img_list}
start = datetime.now()
respond = requests.get('http://127.0.0.1:27010/test', json=data)
prediction = respond.json()['prediction']
print("time for prediction: {}".format(datetime.now()-start))
if __name__=='__main__':
test_speed()
服务器的输出是:
(cera) PS C:\Users\user_name\Desktop\MRM\REST> python .\server.py
[32mINFO[0m: Started server process [[36m20448[0m]
[32mINFO[0m: Waiting for application startup.
[32mINFO[0m: Application startup complete.
[32mINFO[0m: Uvicorn running on [1mhttp://127.0.0.1:27010[0m (Press CTRL+C to quit)
Time to run: 0:00:00.337099
[32mINFO[0m: 127.0.0.1:61631 - "[1mGET /test HTTP/1.1[0m" [32m200 OK[0m
客户端的输出是:
(cera) PS C:\Users\user_name\Desktop\MRM\REST> python .\client.py
time for prediction: 0:00:16.845123
由于服务器上的代码 运行 不到一秒,将图像从客户端传输到服务器(或返回)所需的时间约为 8 秒,这绝对是太长了.
我无法发送较小的图像,因为模型的输入大小需要保持不变。
所以对于 deployment/REST 新手:什么是专业/最佳实践方法来更快地从 REST API 获得我的预测?我假设使用 python 是有限制的,但 16 秒对我来说仍然太长了。
提前致谢!
我建议通读此文档并尝试为您的图片上传路径提供的示例。
正如@slizb 指出的那样,将图像编码为 base64 会使一切变得更快。
而不是 img_list = img.to_list()
使用
data = {'shape': image.shape, 'img': base64.b64encode(image.tobytes())}
在服务器上
image = np.frombuffer(base64.b64decode(data.img)).reshape(data.shape)
确保也发送形状,因为 numpy 不会“记住”缓冲区中的形状,所以我需要手动 .reshape()
图像。
总时间下降到大约 1 秒,这主要是我模型的推理时间。
我不熟悉开发 Rest APIs 并尝试使用 Python 和 Rest APIs 部署机器学习模型进行图像分割。
在服务器端我使用 FastAPI 而在客户端我使用 Python 请求库。客户端已经将图像大小调整为模型的必要输入大小,因此不会发送不必要的大图像。服务器将接收到的图像提供给模型和 returns 二进制分割掩码。图像和蒙版从 numpy 数组转换为列表,然后作为 json 数据发送。
下面是一些代码,代表我刚才描述的内容。由于我无法在此处提供模型,因此这个最小可重现示例中的服务器将 return 接收到的相同图像。
server.py
import uvicorn
from fastapi import FastAPI
import numpy as np
from datetime import datetime
app = FastAPI()
@app.get('/test')
def predict_and_process(data: dict = None):
start = datetime.now()
if data:
image = np.asarray(data['image'])
print("Time to run: ", datetime.now() - start)
return {'prediction': np.squeeze(image).tolist()}
else:
return {'msg': "Model or data not available"}
def run():
PORT = 27010
uvicorn.run(
app,
host="127.0.0.1",
port=PORT,
)
if __name__=='__main__':
run()
client.py
import requests
import numpy as np
import json
from matplotlib.pyplot import imread
from skimage.transform import resize
from datetime import datetime
def test_speed():
path_to_img = r"path_to_some_image"
image = imread(path_to_img)
image = resize(image, (1024, 1024))
img_list = image.tolist()
data = {'image': img_list}
start = datetime.now()
respond = requests.get('http://127.0.0.1:27010/test', json=data)
prediction = respond.json()['prediction']
print("time for prediction: {}".format(datetime.now()-start))
if __name__=='__main__':
test_speed()
服务器的输出是:
(cera) PS C:\Users\user_name\Desktop\MRM\REST> python .\server.py
[32mINFO[0m: Started server process [[36m20448[0m]
[32mINFO[0m: Waiting for application startup.
[32mINFO[0m: Application startup complete.
[32mINFO[0m: Uvicorn running on [1mhttp://127.0.0.1:27010[0m (Press CTRL+C to quit)
Time to run: 0:00:00.337099
[32mINFO[0m: 127.0.0.1:61631 - "[1mGET /test HTTP/1.1[0m" [32m200 OK[0m
客户端的输出是:
(cera) PS C:\Users\user_name\Desktop\MRM\REST> python .\client.py
time for prediction: 0:00:16.845123
由于服务器上的代码 运行 不到一秒,将图像从客户端传输到服务器(或返回)所需的时间约为 8 秒,这绝对是太长了.
我无法发送较小的图像,因为模型的输入大小需要保持不变。
所以对于 deployment/REST 新手:什么是专业/最佳实践方法来更快地从 REST API 获得我的预测?我假设使用 python 是有限制的,但 16 秒对我来说仍然太长了。
提前致谢!
我建议通读此文档并尝试为您的图片上传路径提供的示例。
正如@slizb 指出的那样,将图像编码为 base64 会使一切变得更快。
而不是 img_list = img.to_list()
使用
data = {'shape': image.shape, 'img': base64.b64encode(image.tobytes())}
在服务器上
image = np.frombuffer(base64.b64decode(data.img)).reshape(data.shape)
确保也发送形状,因为 numpy 不会“记住”缓冲区中的形状,所以我需要手动 .reshape()
图像。
总时间下降到大约 1 秒,这主要是我模型的推理时间。