official_models.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. # Copyright (c) 2024 PaddlePaddle Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import os
  15. import shutil
  16. import tempfile
  17. from abc import ABC, abstractmethod
  18. from pathlib import Path
  19. import huggingface_hub as hf_hub
  20. hf_hub.logging.set_verbosity_error()
  21. import modelscope
  22. import requests
  23. os.environ["AISTUDIO_LOG"] = "critical"
  24. from aistudio_sdk.snapshot_download import snapshot_download as aistudio_download
  25. from ...utils import logging
  26. from ...utils.cache import CACHE_DIR
  27. from ...utils.download import download_and_extract
  28. from ...utils.flags import MODEL_SOURCE
  29. ALL_MODELS = [
  30. "ResNet18",
  31. "ResNet18_vd",
  32. "ResNet34",
  33. "ResNet34_vd",
  34. "ResNet50",
  35. "ResNet50_vd",
  36. "ResNet101",
  37. "ResNet101_vd",
  38. "ResNet152",
  39. "ResNet152_vd",
  40. "ResNet200_vd",
  41. "PP-LCNet_x0_25",
  42. "PP-LCNet_x0_25_textline_ori",
  43. "PP-LCNet_x0_35",
  44. "PP-LCNet_x0_5",
  45. "PP-LCNet_x0_75",
  46. "PP-LCNet_x1_0",
  47. "PP-LCNet_x1_0_doc_ori",
  48. "PP-LCNet_x1_0_textline_ori",
  49. "PP-LCNet_x1_5",
  50. "PP-LCNet_x2_5",
  51. "PP-LCNet_x2_0",
  52. "PP-LCNetV2_small",
  53. "PP-LCNetV2_base",
  54. "PP-LCNetV2_large",
  55. "MobileNetV3_large_x0_35",
  56. "MobileNetV3_large_x0_5",
  57. "MobileNetV3_large_x0_75",
  58. "MobileNetV3_large_x1_0",
  59. "MobileNetV3_large_x1_25",
  60. "MobileNetV3_small_x0_35",
  61. "MobileNetV3_small_x0_5",
  62. "MobileNetV3_small_x0_75",
  63. "MobileNetV3_small_x1_0",
  64. "MobileNetV3_small_x1_25",
  65. "ConvNeXt_tiny",
  66. "ConvNeXt_small",
  67. "ConvNeXt_base_224",
  68. "ConvNeXt_base_384",
  69. "ConvNeXt_large_224",
  70. "ConvNeXt_large_384",
  71. "MobileNetV2_x0_25",
  72. "MobileNetV2_x0_5",
  73. "MobileNetV2_x1_0",
  74. "MobileNetV2_x1_5",
  75. "MobileNetV2_x2_0",
  76. "MobileNetV1_x0_25",
  77. "MobileNetV1_x0_5",
  78. "MobileNetV1_x0_75",
  79. "MobileNetV1_x1_0",
  80. "SwinTransformer_tiny_patch4_window7_224",
  81. "SwinTransformer_small_patch4_window7_224",
  82. "SwinTransformer_base_patch4_window7_224",
  83. "SwinTransformer_base_patch4_window12_384",
  84. "SwinTransformer_large_patch4_window7_224",
  85. "SwinTransformer_large_patch4_window12_384",
  86. "PP-HGNet_tiny",
  87. "PP-HGNet_small",
  88. "PP-HGNet_base",
  89. "PP-HGNetV2-B0",
  90. "PP-HGNetV2-B1",
  91. "PP-HGNetV2-B2",
  92. "PP-HGNetV2-B3",
  93. "PP-HGNetV2-B4",
  94. "PP-HGNetV2-B5",
  95. "PP-HGNetV2-B6",
  96. "FasterNet-L",
  97. "FasterNet-M",
  98. "FasterNet-S",
  99. "FasterNet-T0",
  100. "FasterNet-T1",
  101. "FasterNet-T2",
  102. "StarNet-S1",
  103. "StarNet-S2",
  104. "StarNet-S3",
  105. "StarNet-S4",
  106. "MobileNetV4_conv_small",
  107. "MobileNetV4_conv_medium",
  108. "MobileNetV4_conv_large",
  109. "MobileNetV4_hybrid_medium",
  110. "MobileNetV4_hybrid_large",
  111. "CLIP_vit_base_patch16_224",
  112. "CLIP_vit_large_patch14_224",
  113. "PP-LCNet_x1_0_ML",
  114. "PP-HGNetV2-B0_ML",
  115. "PP-HGNetV2-B4_ML",
  116. "PP-HGNetV2-B6_ML",
  117. "ResNet50_ML",
  118. "CLIP_vit_base_patch16_448_ML",
  119. "PP-YOLOE_plus-X",
  120. "PP-YOLOE_plus-L",
  121. "PP-YOLOE_plus-M",
  122. "PP-YOLOE_plus-S",
  123. "RT-DETR-L",
  124. "RT-DETR-H",
  125. "RT-DETR-X",
  126. "YOLOv3-DarkNet53",
  127. "YOLOv3-MobileNetV3",
  128. "YOLOv3-ResNet50_vd_DCN",
  129. "YOLOX-L",
  130. "YOLOX-M",
  131. "YOLOX-N",
  132. "YOLOX-S",
  133. "YOLOX-T",
  134. "YOLOX-X",
  135. "RT-DETR-R18",
  136. "RT-DETR-R50",
  137. "PicoDet-S",
  138. "PicoDet-L",
  139. "Deeplabv3-R50",
  140. "Deeplabv3-R101",
  141. "Deeplabv3_Plus-R50",
  142. "Deeplabv3_Plus-R101",
  143. "PP-ShiTuV2_rec",
  144. "PP-ShiTuV2_rec_CLIP_vit_base",
  145. "PP-ShiTuV2_rec_CLIP_vit_large",
  146. "PP-LiteSeg-T",
  147. "PP-LiteSeg-B",
  148. "OCRNet_HRNet-W48",
  149. "OCRNet_HRNet-W18",
  150. "SegFormer-B0",
  151. "SegFormer-B1",
  152. "SegFormer-B2",
  153. "SegFormer-B3",
  154. "SegFormer-B4",
  155. "SegFormer-B5",
  156. "SeaFormer_tiny",
  157. "SeaFormer_small",
  158. "SeaFormer_base",
  159. "SeaFormer_large",
  160. "Mask-RT-DETR-H",
  161. "Mask-RT-DETR-L",
  162. "PP-OCRv4_server_rec",
  163. "Mask-RT-DETR-S",
  164. "Mask-RT-DETR-M",
  165. "Mask-RT-DETR-X",
  166. "SOLOv2",
  167. "MaskRCNN-ResNet50",
  168. "MaskRCNN-ResNet50-FPN",
  169. "MaskRCNN-ResNet50-vd-FPN",
  170. "MaskRCNN-ResNet101-FPN",
  171. "MaskRCNN-ResNet101-vd-FPN",
  172. "MaskRCNN-ResNeXt101-vd-FPN",
  173. "Cascade-MaskRCNN-ResNet50-FPN",
  174. "Cascade-MaskRCNN-ResNet50-vd-SSLDv2-FPN",
  175. "PP-YOLOE_seg-S",
  176. "PP-OCRv3_mobile_rec",
  177. "en_PP-OCRv3_mobile_rec",
  178. "korean_PP-OCRv3_mobile_rec",
  179. "japan_PP-OCRv3_mobile_rec",
  180. "chinese_cht_PP-OCRv3_mobile_rec",
  181. "te_PP-OCRv3_mobile_rec",
  182. "ka_PP-OCRv3_mobile_rec",
  183. "ta_PP-OCRv3_mobile_rec",
  184. "latin_PP-OCRv3_mobile_rec",
  185. "arabic_PP-OCRv3_mobile_rec",
  186. "cyrillic_PP-OCRv3_mobile_rec",
  187. "devanagari_PP-OCRv3_mobile_rec",
  188. "en_PP-OCRv4_mobile_rec",
  189. "PP-OCRv4_server_rec_doc",
  190. "PP-OCRv4_mobile_rec",
  191. "PP-OCRv4_server_det",
  192. "PP-OCRv4_mobile_det",
  193. "PP-OCRv3_server_det",
  194. "PP-OCRv3_mobile_det",
  195. "PP-OCRv4_server_seal_det",
  196. "PP-OCRv4_mobile_seal_det",
  197. "ch_RepSVTR_rec",
  198. "ch_SVTRv2_rec",
  199. "PP-LCNet_x1_0_pedestrian_attribute",
  200. "PP-LCNet_x1_0_vehicle_attribute",
  201. "PicoDet_layout_1x",
  202. "PicoDet_layout_1x_table",
  203. "SLANet",
  204. "SLANet_plus",
  205. "LaTeX_OCR_rec",
  206. "UniMERNet",
  207. "PP-FormulaNet-S",
  208. "PP-FormulaNet-L",
  209. "PP-FormulaNet_plus-S",
  210. "PP-FormulaNet_plus-M",
  211. "PP-FormulaNet_plus-L",
  212. "FasterRCNN-ResNet34-FPN",
  213. "FasterRCNN-ResNet50",
  214. "FasterRCNN-ResNet50-FPN",
  215. "FasterRCNN-ResNet50-vd-FPN",
  216. "FasterRCNN-ResNet50-vd-SSLDv2-FPN",
  217. "FasterRCNN-ResNet101",
  218. "FasterRCNN-ResNet101-FPN",
  219. "FasterRCNN-ResNeXt101-vd-FPN",
  220. "FasterRCNN-Swin-Tiny-FPN",
  221. "Cascade-FasterRCNN-ResNet50-FPN",
  222. "Cascade-FasterRCNN-ResNet50-vd-SSLDv2-FPN",
  223. "UVDoc",
  224. "DLinear",
  225. "NLinear",
  226. "RLinear",
  227. "Nonstationary",
  228. "TimesNet",
  229. "TiDE",
  230. "PatchTST",
  231. "DLinear_ad",
  232. "AutoEncoder_ad",
  233. "Nonstationary_ad",
  234. "PatchTST_ad",
  235. "TimesNet_ad",
  236. "TimesNet_cls",
  237. "STFPM",
  238. "FCOS-ResNet50",
  239. "DETR-R50",
  240. "PP-YOLOE-L_vehicle",
  241. "PP-YOLOE-S_vehicle",
  242. "PP-ShiTuV2_det",
  243. "PP-YOLOE-S_human",
  244. "PP-YOLOE-L_human",
  245. "PicoDet-M",
  246. "PicoDet-XS",
  247. "PP-YOLOE_plus_SOD-L",
  248. "PP-YOLOE_plus_SOD-S",
  249. "PP-YOLOE_plus_SOD-largesize-L",
  250. "CenterNet-DLA-34",
  251. "CenterNet-ResNet50",
  252. "PicoDet-S_layout_3cls",
  253. "PicoDet-S_layout_17cls",
  254. "PicoDet-L_layout_3cls",
  255. "PicoDet-L_layout_17cls",
  256. "RT-DETR-H_layout_3cls",
  257. "RT-DETR-H_layout_17cls",
  258. "PicoDet_LCNet_x2_5_face",
  259. "BlazeFace",
  260. "BlazeFace-FPN-SSH",
  261. "PP-YOLOE_plus-S_face",
  262. "MobileFaceNet",
  263. "ResNet50_face",
  264. "PP-YOLOE-R-L",
  265. "Co-Deformable-DETR-R50",
  266. "Co-Deformable-DETR-Swin-T",
  267. "Co-DINO-R50",
  268. "Co-DINO-Swin-L",
  269. "whisper_large",
  270. "whisper_base",
  271. "whisper_medium",
  272. "whisper_small",
  273. "whisper_tiny",
  274. "PP-TSM-R50_8frames_uniform",
  275. "PP-TSMv2-LCNetV2_8frames_uniform",
  276. "PP-TSMv2-LCNetV2_16frames_uniform",
  277. "MaskFormer_tiny",
  278. "MaskFormer_small",
  279. "PP-LCNet_x1_0_table_cls",
  280. "SLANeXt_wired",
  281. "SLANeXt_wireless",
  282. "RT-DETR-L_wired_table_cell_det",
  283. "RT-DETR-L_wireless_table_cell_det",
  284. "YOWO",
  285. "PP-TinyPose_128x96",
  286. "PP-TinyPose_256x192",
  287. "GroundingDINO-T",
  288. "SAM-H_box",
  289. "SAM-H_point",
  290. "PP-DocLayout-L",
  291. "PP-DocLayout-M",
  292. "PP-DocLayout-S",
  293. "PP-DocLayout_plus-L",
  294. "PP-DocBlockLayout",
  295. "BEVFusion",
  296. "YOLO-Worldv2-L",
  297. "PP-DocBee-2B",
  298. "PP-DocBee-7B",
  299. "PP-Chart2Table",
  300. "PP-OCRv5_server_det",
  301. "PP-OCRv5_mobile_det",
  302. "PP-OCRv5_server_rec",
  303. "PP-OCRv5_mobile_rec",
  304. "eslav_PP-OCRv5_mobile_rec",
  305. "PP-DocBee2-3B",
  306. "latin_PP-OCRv5_mobile_rec",
  307. "korean_PP-OCRv5_mobile_rec",
  308. ]
  309. OCR_MODELS = [
  310. "arabic_PP-OCRv3_mobile_rec",
  311. "chinese_cht_PP-OCRv3_mobile_rec",
  312. "ch_RepSVTR_rec",
  313. "ch_SVTRv2_rec",
  314. "cyrillic_PP-OCRv3_mobile_rec",
  315. "devanagari_PP-OCRv3_mobile_rec",
  316. "en_PP-OCRv3_mobile_rec",
  317. "en_PP-OCRv4_mobile_rec",
  318. "eslav_PP-OCRv5_mobile_rec",
  319. "japan_PP-OCRv3_mobile_rec",
  320. "ka_PP-OCRv3_mobile_rec",
  321. "korean_PP-OCRv3_mobile_rec",
  322. "korean_PP-OCRv5_mobile_rec",
  323. "LaTeX_OCR_rec",
  324. "latin_PP-OCRv3_mobile_rec",
  325. "latin_PP-OCRv5_mobile_rec",
  326. "PicoDet_layout_1x",
  327. "PicoDet_layout_1x_table",
  328. "PicoDet-L_layout_17cls",
  329. "PicoDet-L_layout_3cls",
  330. "PicoDet-S_layout_17cls",
  331. "PicoDet-S_layout_3cls",
  332. "PP-DocBee2-3B",
  333. "PP-Chart2Table",
  334. "PP-DocBee-2B",
  335. "PP-DocBee-7B",
  336. "PP-DocBlockLayout",
  337. "PP-DocLayout-L",
  338. "PP-DocLayout-M",
  339. "PP-DocLayout_plus-L",
  340. "PP-DocLayout-S",
  341. "PP-FormulaNet-L",
  342. "PP-FormulaNet_plus-L",
  343. "PP-FormulaNet_plus-M",
  344. "PP-FormulaNet_plus-S",
  345. "PP-FormulaNet-S",
  346. "PP-LCNet_x0_25_textline_ori",
  347. "PP-LCNet_x1_0_doc_ori",
  348. "PP-LCNet_x1_0_table_cls",
  349. "PP-LCNet_x1_0_textline_ori",
  350. "PP-OCRv3_mobile_det",
  351. "PP-OCRv3_mobile_rec",
  352. "PP-OCRv3_server_det",
  353. "PP-OCRv4_mobile_det",
  354. "PP-OCRv4_mobile_rec",
  355. "PP-OCRv4_mobile_seal_det",
  356. "PP-OCRv4_server_det",
  357. "PP-OCRv4_server_rec_doc",
  358. "PP-OCRv4_server_rec",
  359. "PP-OCRv4_server_seal_det",
  360. "PP-OCRv5_mobile_det",
  361. "PP-OCRv5_mobile_rec",
  362. "PP-OCRv5_server_det",
  363. "PP-OCRv5_server_rec",
  364. "RT-DETR-H_layout_17cls",
  365. "RT-DETR-H_layout_3cls",
  366. "RT-DETR-L_wired_table_cell_det",
  367. "RT-DETR-L_wireless_table_cell_det",
  368. "SLANet",
  369. "SLANet_plus",
  370. "SLANeXt_wired",
  371. "SLANeXt_wireless",
  372. "ta_PP-OCRv3_mobile_rec",
  373. "te_PP-OCRv3_mobile_rec",
  374. "UniMERNet",
  375. "UVDoc",
  376. ]
  377. class _BaseModelHoster(ABC):
  378. alias = ""
  379. model_list = []
  380. healthcheck_url = None
  381. _healthcheck_timeout = 1
  382. def __init__(self, save_dir):
  383. self._save_dir = save_dir
  384. def get_model(self, model_name):
  385. assert (
  386. model_name in self.model_list
  387. ), f"The model {model_name} is not supported on hosting {self.__class__.__name__}!"
  388. model_dir = self._save_dir / f"{model_name}"
  389. self._download(model_name, model_dir)
  390. return model_dir
  391. @abstractmethod
  392. def _download(self):
  393. raise NotImplementedError
  394. @classmethod
  395. def is_available(cls):
  396. if cls.healthcheck_url is None:
  397. return True
  398. try:
  399. response = requests.head(
  400. cls.healthcheck_url, timeout=cls._healthcheck_timeout
  401. )
  402. return response.ok == True
  403. except Exception:
  404. logging.debug(f"The model hosting platform({cls.__name__}) is unreachable!")
  405. return False
  406. class _BosModelHoster(_BaseModelHoster):
  407. model_list = ALL_MODELS
  408. alias = "bos"
  409. healthcheck_url = "https://paddle-model-ecology.bj.bcebos.com"
  410. version = "paddle3.0.0"
  411. base_url = (
  412. "https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model"
  413. )
  414. special_model_fn = {
  415. "whisper_large": "whisper_large.tar",
  416. "whisper_base": "whisper_base.tar",
  417. "whisper_medium": "whisper_medium.tar",
  418. "whisper_small": "whisper_small.tar",
  419. "whisper_tiny": "whisper_tiny.tar",
  420. }
  421. def _download(self, model_name, save_dir):
  422. if model_name in self.special_model_fn:
  423. fn = self.special_model_fn[model_name]
  424. else:
  425. fn = f"{model_name}_infer.tar"
  426. url = f"{self.base_url}/{self.version}/{fn}"
  427. download_and_extract(url, save_dir.parent, model_name, overwrite=False)
  428. class _HuggingFaceModelHoster(_BaseModelHoster):
  429. model_list = OCR_MODELS
  430. alias = "huggingface"
  431. healthcheck_url = "https://huggingface.co"
  432. def _download(self, model_name, save_dir):
  433. def _clone(local_dir):
  434. hf_hub.snapshot_download(
  435. repo_id=f"PaddlePaddle/{model_name}", local_dir=local_dir
  436. )
  437. if os.path.exists(save_dir):
  438. _clone(save_dir)
  439. else:
  440. with tempfile.TemporaryDirectory() as td:
  441. temp_dir = os.path.join(td, "temp_dir")
  442. _clone(temp_dir)
  443. shutil.move(temp_dir, save_dir)
  444. class _ModelScopeModelHoster(_BaseModelHoster):
  445. model_list = OCR_MODELS
  446. alias = "modelscope"
  447. healthcheck_url = "https://modelscope.cn"
  448. def _download(self, model_name, save_dir):
  449. def _clone(local_dir):
  450. modelscope.snapshot_download(
  451. repo_id=f"PaddlePaddle/{model_name}", local_dir=local_dir
  452. )
  453. if os.path.exists(save_dir):
  454. _clone(save_dir)
  455. else:
  456. with tempfile.TemporaryDirectory() as td:
  457. temp_dir = os.path.join(td, "temp_dir")
  458. _clone(temp_dir)
  459. shutil.move(temp_dir, save_dir)
  460. class _AIStudioModelHoster(_BaseModelHoster):
  461. model_list = OCR_MODELS
  462. alias = "aistudio"
  463. healthcheck_url = "https://aistudio.baidu.com"
  464. def _download(self, model_name, save_dir):
  465. def _clone(local_dir):
  466. aistudio_download(repo_id=f"PaddleX/{model_name}", local_dir=local_dir)
  467. if os.path.exists(save_dir):
  468. _clone(save_dir)
  469. else:
  470. with tempfile.TemporaryDirectory() as td:
  471. temp_dir = os.path.join(td, "temp_dir")
  472. _clone(temp_dir)
  473. shutil.move(temp_dir, save_dir)
  474. class _ModelManager:
  475. model_list = ALL_MODELS
  476. _save_dir = Path(CACHE_DIR) / "official_models"
  477. def __init__(self) -> None:
  478. self._hosters = self._build_hosters()
  479. def _build_hosters(self):
  480. hosters = []
  481. for hoster_cls in [
  482. _HuggingFaceModelHoster,
  483. _AIStudioModelHoster,
  484. _ModelScopeModelHoster,
  485. _BosModelHoster,
  486. ]:
  487. if hoster_cls.alias == MODEL_SOURCE:
  488. if hoster_cls.is_available():
  489. hosters.insert(0, hoster_cls(self._save_dir))
  490. else:
  491. if hoster_cls.is_available():
  492. hosters.append(hoster_cls(self._save_dir))
  493. if len(hosters) == 0:
  494. logging.warning(
  495. f"""No model hoster is available! Please check your network connection to one of the following model hosts:
  496. HuggingFace ({_HuggingFaceModelHoster.healthcheck_url}),
  497. ModelScope ({_ModelScopeModelHoster.healthcheck_url}),
  498. AIStudio ({_AIStudioModelHoster.healthcheck_url}), or
  499. BOS ({_BosModelHoster.healthcheck_url}).
  500. Otherwise, only local models can be used."""
  501. )
  502. return hosters
  503. def _get_model_local_path(self, model_name):
  504. logging.info(
  505. f"Using official model ({model_name}), the model files will be automatically downloaded and saved in {self._save_dir}."
  506. )
  507. if len(self._hosters) == 0:
  508. msg = "No available model hosting platforms detected. Please check your network connection."
  509. logging.error(msg)
  510. raise Exception(msg)
  511. return self._download_from_hoster(self._hosters, model_name)
  512. def _download_from_hoster(self, hosters, model_name):
  513. for idx, hoster in enumerate(hosters):
  514. if model_name in hoster.model_list:
  515. try:
  516. return hoster.get_model(model_name)
  517. except Exception as e:
  518. logging.warning(
  519. f"Encounter exception when download model from {hoster.alias}: \n{e}."
  520. )
  521. if len(hosters) <= 1:
  522. raise Exception(
  523. f"No model source is available! Please check network or use local model files!"
  524. )
  525. logging.warning(
  526. f"PaddleX would try to download from other model sources."
  527. )
  528. return self._download_from_hoster(hosters[idx + 1 :], model_name)
  529. def __contains__(self, model_name):
  530. return model_name in self.model_list
  531. def __getitem__(self, model_name):
  532. return self._get_model_local_path(model_name)
  533. official_models = _ModelManager()