class SampleInfer(Processor):
preprocess: []
pool: paddle.inference.PredictorPool
ids: {}
def __init__(self):
logging.info("Loading model file")
# 加载动态图,并转换为静态图
model = RedNet26(pretrained='/share/PaddleClas/output/RedNet26/latest')
# 静态图需要制定输入的形状,`None`代表可变,例如:本例子中,每次可以同时预测多张图像。
static_mode = paddle.jit.to_static(model, input_spec=[InputSpec(shape=[None, 3, 224, 224], name='x')])
# 保存jit(静态模型)
paddle.jit.save(static_mode, '/share/PaddleClas/output/RedNet26/static/latest')
# 开始模型加载,需要指定两个参数,一个是网络结构,一个是训练参数。此时不再需要RedNet26网络结构了,直接加载就可以了。
config = paddle.inference.Config('/share/PaddleClas/output/RedNet26/static/latest.pdmodel', '/share/PaddleClas/output/RedNet26/static/latest.pdiparams')
# 使用0号显卡的100M显存
config.enable_use_gpu(100, 0)
# predictor不是线程安全的,所以需要创建一个PredictorPool来保证线程的并发安全性。
self.pool = paddle.inference.PredictorPool(config, 4)
# 数据预处理,与训练时一致即可。
self.preprocess = []
self.preprocess.append(DecodeImage(to_rgb=True, channel_first=False))
self.preprocess.append(ResizeImage(resize_short=256))
self.preprocess.append(CropImage(size=224))
self.preprocess.append(NormalizeImage(scale=1.0, mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], order=''))
self.preprocess.append(ToCHWImage())
self.ids = {}
self.idx = 0
def process(self, msg: str):
# 线程号绑定predictor,这里未处理锁,正式代码自行处理一下。
tid = threading.current_thread().ident
if not tid in self.ids:
self.idx += 1
self.ids[tid] = int(self.idx)
idx = self.ids[tid]
logging.info("tid({}) use idx({})".format(tid, idx))
# 第一步:获取图像内容
img = base64.decodebytes(bytes(msg, encoding="utf-8"))
req = img
# 第二步:加载图像内容,并进行预处理(匹配网络输入的数据结构)
for process in self.preprocess:
req = process(req)
# 第三步:升维,因为只有一张图,所以需要升维成4D,以匹配InputSpec
req = np.expand_dims(req, axis=0)
# 第四步:获取本线程绑定的predictor对象
predictor = self.pool.retrive(idx)
# 第五步:开始预测,并获得预测结果
try:
input_names = predictor.get_input_names() # 获得输入参数名称,即'x',在静态图构建过程中使用InputSpec指定的
input_tensor = predictor.get_input_handle(input_names[0])
input_tensor.copy_from_cpu(req) # 将数据从内存中拷贝到GPU(因为本例子使用了gpu做预测)中
predictor.run()
output_names = predictor.get_output_names()
output_tensor = predictor.get_output_handle(output_names[0])
resp = output_tensor.copy_to_cpu() # 将数据从GPU读取到内存中进行处理。
return str(resp.argmax())
finally:
predictor.clear_intermediate_tensor() # 释放中间计算产生的Tensor
predictor.try_shrink_memory() # 释放显存
网友评论