model_init.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import os
  2. import torch
  3. from loguru import logger
  4. from .model_list import AtomicModel
  5. from ...model.layout.doclayoutyolo import DocLayoutYOLOModel
  6. from ...model.mfd.yolo_v8 import YOLOv8MFDModel
  7. from ...model.mfr.unimernet.Unimernet import UnimernetModel
  8. from ...model.mfr.pp_formulanet_plus_m.predict_formula import FormulaRecognizer
  9. from ...model.ocr.paddleocr2pytorch.pytorch_paddle import PytorchPaddleOCR
  10. from ...model.ori_cls.paddle_ori_cls import PaddleOrientationClsModel
  11. from ...model.table.cls.paddle_table_cls import PaddleTableClsModel
  12. # from ...model.table.rec.RapidTable import RapidTableModel
  13. from ...model.table.rec.slanet_plus.main import RapidTableModel
  14. from ...model.table.rec.unet_table.main import UnetTableModel
  15. from ...utils.enum_class import ModelPath
  16. from ...utils.models_download_utils import auto_download_and_get_model_root_path
  17. MFR_MODEL = "unimernet_small"
  18. # MFR_MODEL = "pp_formulanet_plus_m"
  19. def img_orientation_cls_model_init():
  20. atom_model_manager = AtomModelSingleton()
  21. ocr_engine = atom_model_manager.get_atom_model(
  22. atom_model_name=AtomicModel.OCR,
  23. det_db_box_thresh=0.5,
  24. det_db_unclip_ratio=1.6,
  25. lang="ch_lite",
  26. enable_merge_det_boxes=False
  27. )
  28. cls_model = PaddleOrientationClsModel(ocr_engine)
  29. return cls_model
  30. def table_cls_model_init():
  31. return PaddleTableClsModel()
  32. def wired_table_model_init(lang=None):
  33. atom_model_manager = AtomModelSingleton()
  34. ocr_engine = atom_model_manager.get_atom_model(
  35. atom_model_name=AtomicModel.OCR,
  36. det_db_box_thresh=0.5,
  37. det_db_unclip_ratio=1.6,
  38. lang=lang,
  39. enable_merge_det_boxes=False
  40. )
  41. table_model = UnetTableModel(ocr_engine)
  42. return table_model
  43. def wireless_table_model_init(lang=None):
  44. atom_model_manager = AtomModelSingleton()
  45. ocr_engine = atom_model_manager.get_atom_model(
  46. atom_model_name=AtomicModel.OCR,
  47. det_db_box_thresh=0.5,
  48. det_db_unclip_ratio=1.6,
  49. lang=lang,
  50. enable_merge_det_boxes=False
  51. )
  52. table_model = RapidTableModel(ocr_engine)
  53. return table_model
  54. def mfd_model_init(weight, device='cpu'):
  55. if str(device).startswith('npu'):
  56. device = torch.device(device)
  57. mfd_model = YOLOv8MFDModel(weight, device)
  58. return mfd_model
  59. def mfr_model_init(weight_dir, device='cpu'):
  60. if MFR_MODEL == "unimernet_small":
  61. mfr_model = UnimernetModel(weight_dir, device)
  62. elif MFR_MODEL == "pp_formulanet_plus_m":
  63. mfr_model = FormulaRecognizer(weight_dir, device)
  64. else:
  65. logger.error('MFR model name not allow')
  66. exit(1)
  67. return mfr_model
  68. def doclayout_yolo_model_init(weight, device='cpu'):
  69. if str(device).startswith('npu'):
  70. device = torch.device(device)
  71. model = DocLayoutYOLOModel(weight, device)
  72. return model
  73. def ocr_model_init(det_db_box_thresh=0.3,
  74. lang=None,
  75. det_db_unclip_ratio=1.8,
  76. enable_merge_det_boxes=True
  77. ):
  78. if lang is not None and lang != '':
  79. model = PytorchPaddleOCR(
  80. det_db_box_thresh=det_db_box_thresh,
  81. lang=lang,
  82. use_dilation=True,
  83. det_db_unclip_ratio=det_db_unclip_ratio,
  84. enable_merge_det_boxes=enable_merge_det_boxes,
  85. )
  86. else:
  87. model = PytorchPaddleOCR(
  88. det_db_box_thresh=det_db_box_thresh,
  89. use_dilation=True,
  90. det_db_unclip_ratio=det_db_unclip_ratio,
  91. enable_merge_det_boxes=enable_merge_det_boxes,
  92. )
  93. return model
  94. class AtomModelSingleton:
  95. _instance = None
  96. _models = {}
  97. def __new__(cls, *args, **kwargs):
  98. if cls._instance is None:
  99. cls._instance = super().__new__(cls)
  100. return cls._instance
  101. def get_atom_model(self, atom_model_name: str, **kwargs):
  102. lang = kwargs.get('lang', None)
  103. if atom_model_name in [AtomicModel.WiredTable, AtomicModel.WirelessTable]:
  104. key = (
  105. atom_model_name,
  106. lang
  107. )
  108. elif atom_model_name in [AtomicModel.OCR]:
  109. key = (
  110. atom_model_name,
  111. kwargs.get('det_db_box_thresh', 0.3),
  112. lang,
  113. kwargs.get('det_db_unclip_ratio', 1.8),
  114. kwargs.get('enable_merge_det_boxes', True)
  115. )
  116. else:
  117. key = atom_model_name
  118. if key not in self._models:
  119. self._models[key] = atom_model_init(model_name=atom_model_name, **kwargs)
  120. return self._models[key]
  121. def atom_model_init(model_name: str, **kwargs):
  122. atom_model = None
  123. if model_name == AtomicModel.Layout:
  124. atom_model = doclayout_yolo_model_init(
  125. kwargs.get('doclayout_yolo_weights'),
  126. kwargs.get('device')
  127. )
  128. elif model_name == AtomicModel.MFD:
  129. atom_model = mfd_model_init(
  130. kwargs.get('mfd_weights'),
  131. kwargs.get('device')
  132. )
  133. elif model_name == AtomicModel.MFR:
  134. atom_model = mfr_model_init(
  135. kwargs.get('mfr_weight_dir'),
  136. kwargs.get('device')
  137. )
  138. elif model_name == AtomicModel.OCR:
  139. atom_model = ocr_model_init(
  140. kwargs.get('det_db_box_thresh', 0.3),
  141. kwargs.get('lang'),
  142. kwargs.get('det_db_unclip_ratio', 1.8),
  143. kwargs.get('enable_merge_det_boxes', True)
  144. )
  145. elif model_name == AtomicModel.WirelessTable:
  146. atom_model = wireless_table_model_init(
  147. kwargs.get('lang'),
  148. )
  149. elif model_name == AtomicModel.WiredTable:
  150. atom_model = wired_table_model_init(
  151. kwargs.get('lang'),
  152. )
  153. elif model_name == AtomicModel.TableCls:
  154. atom_model = table_cls_model_init()
  155. elif model_name == AtomicModel.ImgOrientationCls:
  156. atom_model = img_orientation_cls_model_init()
  157. else:
  158. logger.error('model name not allow')
  159. exit(1)
  160. if atom_model is None:
  161. logger.error('model init failed')
  162. exit(1)
  163. else:
  164. return atom_model
  165. class MineruPipelineModel:
  166. def __init__(self, **kwargs):
  167. self.formula_config = kwargs.get('formula_config')
  168. self.apply_formula = self.formula_config.get('enable', True)
  169. self.table_config = kwargs.get('table_config')
  170. self.apply_table = self.table_config.get('enable', True)
  171. self.lang = kwargs.get('lang', None)
  172. self.device = kwargs.get('device', 'cpu')
  173. logger.info(
  174. 'DocAnalysis init, this may take some times......'
  175. )
  176. atom_model_manager = AtomModelSingleton()
  177. if self.apply_formula:
  178. # 初始化公式检测模型
  179. self.mfd_model = atom_model_manager.get_atom_model(
  180. atom_model_name=AtomicModel.MFD,
  181. mfd_weights=str(
  182. os.path.join(auto_download_and_get_model_root_path(ModelPath.yolo_v8_mfd), ModelPath.yolo_v8_mfd)
  183. ),
  184. device=self.device,
  185. )
  186. # 初始化公式解析模型
  187. if MFR_MODEL == "unimernet_small":
  188. mfr_model_path = ModelPath.unimernet_small
  189. elif MFR_MODEL == "pp_formulanet_plus_m":
  190. mfr_model_path = ModelPath.pp_formulanet_plus_m
  191. else:
  192. logger.error('MFR model name not allow')
  193. exit(1)
  194. self.mfr_model = atom_model_manager.get_atom_model(
  195. atom_model_name=AtomicModel.MFR,
  196. mfr_weight_dir=str(os.path.join(auto_download_and_get_model_root_path(mfr_model_path), mfr_model_path)),
  197. device=self.device,
  198. )
  199. # 初始化layout模型
  200. self.layout_model = atom_model_manager.get_atom_model(
  201. atom_model_name=AtomicModel.Layout,
  202. doclayout_yolo_weights=str(
  203. os.path.join(auto_download_and_get_model_root_path(ModelPath.doclayout_yolo), ModelPath.doclayout_yolo)
  204. ),
  205. device=self.device,
  206. )
  207. # 初始化ocr
  208. self.ocr_model = atom_model_manager.get_atom_model(
  209. atom_model_name=AtomicModel.OCR,
  210. det_db_box_thresh=0.3,
  211. lang=self.lang
  212. )
  213. # init table model
  214. if self.apply_table:
  215. self.wired_table_model = atom_model_manager.get_atom_model(
  216. atom_model_name=AtomicModel.WiredTable,
  217. lang=self.lang,
  218. )
  219. self.wireless_table_model = atom_model_manager.get_atom_model(
  220. atom_model_name=AtomicModel.WirelessTable,
  221. lang=self.lang,
  222. )
  223. self.table_cls_model = atom_model_manager.get_atom_model(
  224. atom_model_name=AtomicModel.TableCls,
  225. )
  226. self.img_orientation_cls_model = atom_model_manager.get_atom_model(
  227. atom_model_name=AtomicModel.ImgOrientationCls,
  228. lang=self.lang,
  229. )
  230. logger.info('DocAnalysis init done!')