RapidAI/RapidOCR

建议: 将ppocr_keys等信息直接存储到onnx模型

AutumnSun1996 opened this issue · 7 comments

建议将ppocr_keys, rec_img_shape等信息直接存储到onnx模型

目前, ppocr_keys是单独存放在txt文件, 然后在config.yaml中配置文件路径; rec_img_shape是在config.yaml中配置
这两个参数是和onnx模型强相关的, 可以直接作为元数据存储到onnx模型内, 减少配置的需求.
尤其是ppocr_keys, 目前通过另一个文件来分发, 容易出现两边不一致的情况.
ONNX本身支持自定义元信息的存储. 使用这种方式, 部署相关的配置应该会更简单.

参考代码:

# 添加meta信息
import onnx

model = onnx.load_model('/path/to/model.onnx')
meta = model.metadata_props.add()
meta.key = 'dictionary'
meta.value = open('/path/to/ppocr_keys_v1.txt', 'r', -1, 'u8').read()

meta = model.metadata_props.add()
meta.key = 'shape'
meta.value = '[3,48,320]'

onnx.save_model(model, '/path/to/model.onnx')

# 获取meta信息
import json
import onnxruntime as ort

sess = ort.InferenceSession('/path/to/model.onnx')
metamap = sess.get_modelmeta().custom_metadata_map
chars = metamap['dictionary'].splitlines()
input_shape = json.loads(metamap['shape'])
SWHL commented

好主意,我去调研一下。

SWHL commented
  • 感谢您的建议,我这里已经采纳,同时已经将你添加到致谢列表中。
  • 此次更新:
    • 只把字典文件写入到onnx模型,shape并没有写入,原因是字典文件外部依赖较为严重。
    • 同时兼容了之前的调用方式,可直接读取onnx中的字典,也可读取外部字典文件。
  • 仍存在问题:
    • OpenVINO咱不能读取onnx中的metadata信息。详情参见:openvino issue,所以基于openvino的推理代码仍然是依赖txt的字典文件,但是我已经将该字典文件移入rec模块内部,从外部使用来看,做到了和onnxruntime的统一。

再次感谢。

SWHL commented

issue,我这里先关闭了,以后有问题或者建议可以再次打开。

character_dict_path 这个怎么指定?报错了

rapid_ocr = RapidOCR(use_text_det=False,
rec_model_path =r"L:\jpres34\jpres34.onnx",

character_dict_path=r"F:\japan_dict.txt",

keys_path=r"F:\japan_dict.txt",
)

File "F:\pycharm2020.2\RapidStructure-0.0.0\rapidocr_onnxruntime\rapid_ocr_api.py", line 43, in init
self.text_recognizer = TextRecognizer(config['Rec'])
File "F:\pycharm2020.2\RapidStructure-0.0.0\rapidocr_onnxruntime\ch_ppocr_v3_rec\text_recognize.py", line 35, in init
self.postprocess_op = CTCLabelDecode(self.character_dict_path)
File "F:\pycharm2020.2\RapidStructure-0.0.0\rapidocr_onnxruntime\ch_ppocr_v3_rec\utils.py", line 14, in init
assert character_dict_path is not None, "character_dict_path should not be None"
AssertionError: character_dict_path should not be None

 if self.session.have_key():
        self.character_dict_path = self.session.get_character_list()
    else:
        self.character_dict_path = config.get('keys_path', None)
 在这里加入可以使用,不知道怎么在测试时传入该参数 =======>  self.character_dict_path = r"F:\japan_dict.txt"
    self.postprocess_op = CTCLabelDecode(self.character_dict_path)

用1楼的代码可以存入字典信息了

import onnx

model_path = r'L:\resnet34\4lan\res34.onnx'
model = onnx.load_model(model_path)
meta = model.metadata_props.add()

meta.key = 'dictionary'

meta.key = 'character'

meta.value = open('/path/to/ppocr_keys_v1.txt', 'r', -1, 'u8').read()

meta.value = open(r'F:/japan_dict.txt', 'r', -1, 'u8').read()

meta = model.metadata_props.add()
meta.key = 'shape'
meta.value = '[3,48,320]'

model_path_save = r'L:\resnet34\4lan\res34_withDictPath.onnx'

onnx.save_model(model, '/path/to/model.onnx')

onnx.save_model(model, model_path_save )

获取meta信息

import json
import onnxruntime as ort

sess = ort.InferenceSession('/path/to/model.onnx')

sess = ort.InferenceSession(model_path_save)
metamap = sess.get_modelmeta().custom_metadata_map

chars = metamap['dictionary'].splitlines()

chars = metamap['character'].splitlines()
input_shape = json.loads(metamap['shape'])
print(chars)

SWHL commented

目前仓库最新版,已经这么干了。可下载的识别模型里面都有对应的字典了。