mblt-vision-python 0.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (404) hide show
  1. mblt_vision/__init__.py +86 -0
  2. mblt_vision/_api.py +53 -0
  3. mblt_vision/_compat.py +227 -0
  4. mblt_vision/_model_paths.py +137 -0
  5. mblt_vision/_tasks.py +30 -0
  6. mblt_vision/benchmark/__init__.py +1 -0
  7. mblt_vision/benchmark/argparse_utils.py +106 -0
  8. mblt_vision/benchmark/chart_utils.py +146 -0
  9. mblt_vision/benchmark/io_utils.py +64 -0
  10. mblt_vision/benchmark/summary_utils.py +770 -0
  11. mblt_vision/cli/__init__.py +5 -0
  12. mblt_vision/cli/__main__.py +5 -0
  13. mblt_vision/cli/_vision.py +337 -0
  14. mblt_vision/cli/compile.py +117 -0
  15. mblt_vision/cli/main.py +35 -0
  16. mblt_vision/cli/predict.py +64 -0
  17. mblt_vision/cli/val.py +562 -0
  18. mblt_vision/compile/__init__.py +21 -0
  19. mblt_vision/compile/vision.py +1120 -0
  20. mblt_vision/datasets/__init__.py +15 -0
  21. mblt_vision/datasets/ade20k.yaml +164 -0
  22. mblt_vision/datasets/cityscapes.yaml +54 -0
  23. mblt_vision/datasets/coco.yaml +178 -0
  24. mblt_vision/datasets/dotav1.yaml +28 -0
  25. mblt_vision/datasets/imagenet.yaml +1019 -0
  26. mblt_vision/datasets/imagenet_synsets.txt +1000 -0
  27. mblt_vision/datasets/nyu-depth.yaml +7 -0
  28. mblt_vision/datasets/registry.py +158 -0
  29. mblt_vision/datasets/widerface.yaml +9 -0
  30. mblt_vision/depth_estimation/__init__.py +19 -0
  31. mblt_vision/face_detection/__init__.py +43 -0
  32. mblt_vision/image_classification/__init__.py +311 -0
  33. mblt_vision/instance_segmentation/__init__.py +65 -0
  34. mblt_vision/models/AlexNet.yaml +23 -0
  35. mblt_vision/models/CAFormer_B36.yaml +22 -0
  36. mblt_vision/models/CAFormer_M36.yaml +22 -0
  37. mblt_vision/models/CAFormer_S18.yaml +22 -0
  38. mblt_vision/models/CAFormer_S36.yaml +22 -0
  39. mblt_vision/models/CoAtNet_0_RW_224.yaml +22 -0
  40. mblt_vision/models/CoAtNet_1_RW_224.yaml +22 -0
  41. mblt_vision/models/CoAtNet_2_RW_224.yaml +22 -0
  42. mblt_vision/models/ConvFormer_B36.yaml +22 -0
  43. mblt_vision/models/ConvFormer_M36.yaml +22 -0
  44. mblt_vision/models/ConvFormer_S18.yaml +22 -0
  45. mblt_vision/models/ConvFormer_S36.yaml +22 -0
  46. mblt_vision/models/ConvNext_Base.yaml +23 -0
  47. mblt_vision/models/ConvNext_Large.yaml +23 -0
  48. mblt_vision/models/ConvNext_Small.yaml +23 -0
  49. mblt_vision/models/ConvNext_Tiny.yaml +23 -0
  50. mblt_vision/models/DeiT3_Base_Patch16_224.yaml +22 -0
  51. mblt_vision/models/DeiT3_Base_Patch16_384.yaml +22 -0
  52. mblt_vision/models/DeiT3_Large_Patch16_224.yaml +22 -0
  53. mblt_vision/models/DeiT3_Large_Patch16_384.yaml +22 -0
  54. mblt_vision/models/DeiT3_Medium_Patch16_224.yaml +22 -0
  55. mblt_vision/models/DeiT3_Small_Patch16_224.yaml +22 -0
  56. mblt_vision/models/DeiT3_Small_Patch16_384.yaml +22 -0
  57. mblt_vision/models/DeiT_Base_Patch16_224.yaml +22 -0
  58. mblt_vision/models/DeiT_Base_Patch16_384.yaml +22 -0
  59. mblt_vision/models/DeiT_Small_Patch16_224.yaml +22 -0
  60. mblt_vision/models/DeiT_Tiny_Patch16_224.yaml +22 -0
  61. mblt_vision/models/DenseNet121.yaml +23 -0
  62. mblt_vision/models/DenseNet161.yaml +23 -0
  63. mblt_vision/models/DenseNet169.yaml +23 -0
  64. mblt_vision/models/DenseNet201.yaml +23 -0
  65. mblt_vision/models/EfficientFormer_L1.yaml +22 -0
  66. mblt_vision/models/EfficientFormer_L3.yaml +22 -0
  67. mblt_vision/models/EfficientFormer_L7.yaml +22 -0
  68. mblt_vision/models/EfficientNet_B0.yaml +23 -0
  69. mblt_vision/models/EfficientNet_B1.yaml +32 -0
  70. mblt_vision/models/EfficientNet_B2.yaml +23 -0
  71. mblt_vision/models/EfficientNet_B3.yaml +23 -0
  72. mblt_vision/models/EfficientNet_B4.yaml +23 -0
  73. mblt_vision/models/EfficientNet_B5.yaml +23 -0
  74. mblt_vision/models/EfficientNet_B6.yaml +23 -0
  75. mblt_vision/models/EfficientNet_B7.yaml +23 -0
  76. mblt_vision/models/EfficientNet_V2_L.yaml +23 -0
  77. mblt_vision/models/EfficientNet_V2_M.yaml +23 -0
  78. mblt_vision/models/EfficientNet_V2_S.yaml +23 -0
  79. mblt_vision/models/FlexiVit_Base.yaml +22 -0
  80. mblt_vision/models/FlexiVit_Large.yaml +22 -0
  81. mblt_vision/models/FlexiVit_Small.yaml +22 -0
  82. mblt_vision/models/GELANc-seg.yaml +29 -0
  83. mblt_vision/models/GELANc.yaml +28 -0
  84. mblt_vision/models/GELANe.yaml +28 -0
  85. mblt_vision/models/GELANm.yaml +28 -0
  86. mblt_vision/models/GELANs.yaml +28 -0
  87. mblt_vision/models/GoogLeNet.yaml +23 -0
  88. mblt_vision/models/Inception_V3.yaml +23 -0
  89. mblt_vision/models/LeViT_Conv_128.yaml +22 -0
  90. mblt_vision/models/LeViT_Conv_128S.yaml +22 -0
  91. mblt_vision/models/LeViT_Conv_192.yaml +22 -0
  92. mblt_vision/models/LeViT_Conv_256.yaml +22 -0
  93. mblt_vision/models/LeViT_Conv_384.yaml +22 -0
  94. mblt_vision/models/MNASNet0_5.yaml +23 -0
  95. mblt_vision/models/MNASNet0_75.yaml +23 -0
  96. mblt_vision/models/MNASNet1_0.yaml +23 -0
  97. mblt_vision/models/MNASNet1_3.yaml +23 -0
  98. mblt_vision/models/MobileNet_V2.yaml +32 -0
  99. mblt_vision/models/MobileNet_V3_Large.yaml +32 -0
  100. mblt_vision/models/MobileNet_V3_Small.yaml +23 -0
  101. mblt_vision/models/RegNet_X_16GF.yaml +32 -0
  102. mblt_vision/models/RegNet_X_1_6GF.yaml +32 -0
  103. mblt_vision/models/RegNet_X_32GF.yaml +32 -0
  104. mblt_vision/models/RegNet_X_3_2GF.yaml +32 -0
  105. mblt_vision/models/RegNet_X_400MF.yaml +32 -0
  106. mblt_vision/models/RegNet_X_800MF.yaml +32 -0
  107. mblt_vision/models/RegNet_X_8GF.yaml +32 -0
  108. mblt_vision/models/RegNet_Y_16GF.yaml +76 -0
  109. mblt_vision/models/RegNet_Y_1_6GF.yaml +32 -0
  110. mblt_vision/models/RegNet_Y_32GF.yaml +76 -0
  111. mblt_vision/models/RegNet_Y_3_2GF.yaml +32 -0
  112. mblt_vision/models/RegNet_Y_400MF.yaml +32 -0
  113. mblt_vision/models/RegNet_Y_800MF.yaml +32 -0
  114. mblt_vision/models/RegNet_Y_8GF.yaml +32 -0
  115. mblt_vision/models/RepViT_M0_9.yaml +22 -0
  116. mblt_vision/models/RepViT_M1.yaml +22 -0
  117. mblt_vision/models/RepViT_M1_0.yaml +22 -0
  118. mblt_vision/models/RepViT_M1_1.yaml +22 -0
  119. mblt_vision/models/RepViT_M1_5.yaml +22 -0
  120. mblt_vision/models/RepViT_M2.yaml +22 -0
  121. mblt_vision/models/RepViT_M2_3.yaml +22 -0
  122. mblt_vision/models/RepViT_M3.yaml +22 -0
  123. mblt_vision/models/ResNeXt101_32X8D.yaml +32 -0
  124. mblt_vision/models/ResNeXt101_64X4D.yaml +23 -0
  125. mblt_vision/models/ResNeXt50_32X4D.yaml +32 -0
  126. mblt_vision/models/ResNet101.yaml +32 -0
  127. mblt_vision/models/ResNet152.yaml +32 -0
  128. mblt_vision/models/ResNet18.yaml +23 -0
  129. mblt_vision/models/ResNet34.yaml +23 -0
  130. mblt_vision/models/ResNet50.yaml +32 -0
  131. mblt_vision/models/ShuffleNet_V2_X0_5.yaml +23 -0
  132. mblt_vision/models/ShuffleNet_V2_X1_0.yaml +23 -0
  133. mblt_vision/models/ShuffleNet_V2_X1_5.yaml +23 -0
  134. mblt_vision/models/ShuffleNet_V2_X2_0.yaml +23 -0
  135. mblt_vision/models/SqueezeNet1_0.yaml +23 -0
  136. mblt_vision/models/SqueezeNet1_1.yaml +23 -0
  137. mblt_vision/models/Swin_B.yaml +23 -0
  138. mblt_vision/models/Swin_S.yaml +23 -0
  139. mblt_vision/models/Swin_T.yaml +23 -0
  140. mblt_vision/models/VGG11.yaml +23 -0
  141. mblt_vision/models/VGG11_BN.yaml +23 -0
  142. mblt_vision/models/VGG13.yaml +23 -0
  143. mblt_vision/models/VGG13_BN.yaml +23 -0
  144. mblt_vision/models/VGG16.yaml +23 -0
  145. mblt_vision/models/VGG16_BN.yaml +23 -0
  146. mblt_vision/models/VGG19.yaml +23 -0
  147. mblt_vision/models/VGG19_BN.yaml +23 -0
  148. mblt_vision/models/ViT_B_16.yaml +67 -0
  149. mblt_vision/models/ViT_B_32.yaml +23 -0
  150. mblt_vision/models/ViT_Base_Patch16_224.yaml +22 -0
  151. mblt_vision/models/ViT_Base_Patch16_384.yaml +22 -0
  152. mblt_vision/models/ViT_Base_Patch32_224.yaml +22 -0
  153. mblt_vision/models/ViT_Base_Patch32_384.yaml +22 -0
  154. mblt_vision/models/ViT_Base_Patch8_224.yaml +22 -0
  155. mblt_vision/models/ViT_L_16.yaml +67 -0
  156. mblt_vision/models/ViT_L_32.yaml +23 -0
  157. mblt_vision/models/ViT_Large_Patch16_224.yaml +22 -0
  158. mblt_vision/models/ViT_Large_Patch16_384.yaml +22 -0
  159. mblt_vision/models/ViT_Large_Patch32_384.yaml +22 -0
  160. mblt_vision/models/ViT_Small_Patch16_224.yaml +22 -0
  161. mblt_vision/models/ViT_Small_Patch16_384.yaml +22 -0
  162. mblt_vision/models/ViT_Small_Patch32_224.yaml +22 -0
  163. mblt_vision/models/ViT_Small_Patch32_384.yaml +22 -0
  164. mblt_vision/models/ViT_Tiny_Patch16_224.yaml +22 -0
  165. mblt_vision/models/ViT_Tiny_Patch16_384.yaml +22 -0
  166. mblt_vision/models/VisFormer_Small.yaml +22 -0
  167. mblt_vision/models/VisFormer_Tiny.yaml +22 -0
  168. mblt_vision/models/Wide_ResNet101_2.yaml +32 -0
  169. mblt_vision/models/Wide_ResNet50_2.yaml +32 -0
  170. mblt_vision/models/YOLO11l-cls.yaml +23 -0
  171. mblt_vision/models/YOLO11l-face.yaml +27 -0
  172. mblt_vision/models/YOLO11l-obb.yaml +28 -0
  173. mblt_vision/models/YOLO11l-pose.yaml +28 -0
  174. mblt_vision/models/YOLO11l-seg.yaml +28 -0
  175. mblt_vision/models/YOLO11l.yaml +27 -0
  176. mblt_vision/models/YOLO11m-cls.yaml +23 -0
  177. mblt_vision/models/YOLO11m-face.yaml +27 -0
  178. mblt_vision/models/YOLO11m-obb.yaml +28 -0
  179. mblt_vision/models/YOLO11m-pose.yaml +28 -0
  180. mblt_vision/models/YOLO11m-seg.yaml +28 -0
  181. mblt_vision/models/YOLO11m.yaml +27 -0
  182. mblt_vision/models/YOLO11n-cls.yaml +23 -0
  183. mblt_vision/models/YOLO11n-face.yaml +27 -0
  184. mblt_vision/models/YOLO11n-obb.yaml +28 -0
  185. mblt_vision/models/YOLO11n-pose.yaml +28 -0
  186. mblt_vision/models/YOLO11n-seg.yaml +28 -0
  187. mblt_vision/models/YOLO11n.yaml +27 -0
  188. mblt_vision/models/YOLO11s-cls.yaml +23 -0
  189. mblt_vision/models/YOLO11s-face.yaml +27 -0
  190. mblt_vision/models/YOLO11s-obb.yaml +28 -0
  191. mblt_vision/models/YOLO11s-pose.yaml +28 -0
  192. mblt_vision/models/YOLO11s-seg.yaml +28 -0
  193. mblt_vision/models/YOLO11s.yaml +27 -0
  194. mblt_vision/models/YOLO11x-cls.yaml +23 -0
  195. mblt_vision/models/YOLO11x-obb.yaml +28 -0
  196. mblt_vision/models/YOLO11x-pose.yaml +28 -0
  197. mblt_vision/models/YOLO11x-seg.yaml +28 -0
  198. mblt_vision/models/YOLO11x.yaml +27 -0
  199. mblt_vision/models/YOLO12l-face.yaml +27 -0
  200. mblt_vision/models/YOLO12l-seg.yaml +28 -0
  201. mblt_vision/models/YOLO12l.yaml +27 -0
  202. mblt_vision/models/YOLO12m-face.yaml +27 -0
  203. mblt_vision/models/YOLO12m-seg.yaml +28 -0
  204. mblt_vision/models/YOLO12m.yaml +27 -0
  205. mblt_vision/models/YOLO12n-face.yaml +27 -0
  206. mblt_vision/models/YOLO12n-seg.yaml +28 -0
  207. mblt_vision/models/YOLO12n.yaml +27 -0
  208. mblt_vision/models/YOLO12s-face.yaml +27 -0
  209. mblt_vision/models/YOLO12s-seg.yaml +28 -0
  210. mblt_vision/models/YOLO12s.yaml +27 -0
  211. mblt_vision/models/YOLO12x-seg.yaml +28 -0
  212. mblt_vision/models/YOLO12x.yaml +27 -0
  213. mblt_vision/models/YOLO26l-cls.yaml +23 -0
  214. mblt_vision/models/YOLO26l-depth.yaml +17 -0
  215. mblt_vision/models/YOLO26l-distill.yaml +27 -0
  216. mblt_vision/models/YOLO26l-obb.yaml +28 -0
  217. mblt_vision/models/YOLO26l-pose.yaml +28 -0
  218. mblt_vision/models/YOLO26l-seg.yaml +28 -0
  219. mblt_vision/models/YOLO26l-sem-ade20k.yaml +17 -0
  220. mblt_vision/models/YOLO26l-sem.yaml +17 -0
  221. mblt_vision/models/YOLO26l.yaml +27 -0
  222. mblt_vision/models/YOLO26m-cls.yaml +23 -0
  223. mblt_vision/models/YOLO26m-depth.yaml +17 -0
  224. mblt_vision/models/YOLO26m-distill.yaml +27 -0
  225. mblt_vision/models/YOLO26m-obb.yaml +28 -0
  226. mblt_vision/models/YOLO26m-pose.yaml +28 -0
  227. mblt_vision/models/YOLO26m-seg.yaml +28 -0
  228. mblt_vision/models/YOLO26m-sem-ade20k.yaml +17 -0
  229. mblt_vision/models/YOLO26m-sem.yaml +17 -0
  230. mblt_vision/models/YOLO26m.yaml +27 -0
  231. mblt_vision/models/YOLO26n-cls.yaml +23 -0
  232. mblt_vision/models/YOLO26n-depth.yaml +17 -0
  233. mblt_vision/models/YOLO26n-distill.yaml +27 -0
  234. mblt_vision/models/YOLO26n-obb.yaml +28 -0
  235. mblt_vision/models/YOLO26n-pose.yaml +28 -0
  236. mblt_vision/models/YOLO26n-seg.yaml +28 -0
  237. mblt_vision/models/YOLO26n-sem-ade20k.yaml +17 -0
  238. mblt_vision/models/YOLO26n-sem.yaml +17 -0
  239. mblt_vision/models/YOLO26n.yaml +27 -0
  240. mblt_vision/models/YOLO26s-cls.yaml +23 -0
  241. mblt_vision/models/YOLO26s-depth.yaml +17 -0
  242. mblt_vision/models/YOLO26s-distill.yaml +27 -0
  243. mblt_vision/models/YOLO26s-obb.yaml +28 -0
  244. mblt_vision/models/YOLO26s-pose.yaml +28 -0
  245. mblt_vision/models/YOLO26s-seg.yaml +28 -0
  246. mblt_vision/models/YOLO26s-sem-ade20k.yaml +17 -0
  247. mblt_vision/models/YOLO26s-sem.yaml +17 -0
  248. mblt_vision/models/YOLO26s.yaml +27 -0
  249. mblt_vision/models/YOLO26x-cls.yaml +23 -0
  250. mblt_vision/models/YOLO26x-depth.yaml +17 -0
  251. mblt_vision/models/YOLO26x-distill.yaml +27 -0
  252. mblt_vision/models/YOLO26x-obb.yaml +28 -0
  253. mblt_vision/models/YOLO26x-pose.yaml +28 -0
  254. mblt_vision/models/YOLO26x-seg.yaml +28 -0
  255. mblt_vision/models/YOLO26x-sem-ade20k.yaml +17 -0
  256. mblt_vision/models/YOLO26x-sem.yaml +17 -0
  257. mblt_vision/models/YOLO26x.yaml +27 -0
  258. mblt_vision/models/YOLOv10b.yaml +28 -0
  259. mblt_vision/models/YOLOv10l-face.yaml +28 -0
  260. mblt_vision/models/YOLOv10l.yaml +28 -0
  261. mblt_vision/models/YOLOv10m-face.yaml +28 -0
  262. mblt_vision/models/YOLOv10m.yaml +28 -0
  263. mblt_vision/models/YOLOv10n-face.yaml +28 -0
  264. mblt_vision/models/YOLOv10n.yaml +28 -0
  265. mblt_vision/models/YOLOv10s-face.yaml +28 -0
  266. mblt_vision/models/YOLOv10s.yaml +28 -0
  267. mblt_vision/models/YOLOv10x.yaml +28 -0
  268. mblt_vision/models/YOLOv3-spp.yaml +44 -0
  269. mblt_vision/models/YOLOv3-sppu.yaml +27 -0
  270. mblt_vision/models/YOLOv3-tiny.yaml +38 -0
  271. mblt_vision/models/YOLOv3-tinyu.yaml +27 -0
  272. mblt_vision/models/YOLOv3.yaml +44 -0
  273. mblt_vision/models/YOLOv3u.yaml +27 -0
  274. mblt_vision/models/YOLOv5l-cls.yaml +22 -0
  275. mblt_vision/models/YOLOv5l-seg.yaml +45 -0
  276. mblt_vision/models/YOLOv5l.yaml +44 -0
  277. mblt_vision/models/YOLOv5l6.yaml +50 -0
  278. mblt_vision/models/YOLOv5l6u.yaml +27 -0
  279. mblt_vision/models/YOLOv5lu.yaml +27 -0
  280. mblt_vision/models/YOLOv5m-cls.yaml +22 -0
  281. mblt_vision/models/YOLOv5m-seg.yaml +45 -0
  282. mblt_vision/models/YOLOv5m.yaml +45 -0
  283. mblt_vision/models/YOLOv5m6.yaml +50 -0
  284. mblt_vision/models/YOLOv5m6u.yaml +27 -0
  285. mblt_vision/models/YOLOv5mu.yaml +27 -0
  286. mblt_vision/models/YOLOv5n-cls.yaml +22 -0
  287. mblt_vision/models/YOLOv5n-seg.yaml +45 -0
  288. mblt_vision/models/YOLOv5n.yaml +44 -0
  289. mblt_vision/models/YOLOv5n6.yaml +50 -0
  290. mblt_vision/models/YOLOv5n6u.yaml +27 -0
  291. mblt_vision/models/YOLOv5nu.yaml +27 -0
  292. mblt_vision/models/YOLOv5s-cls.yaml +22 -0
  293. mblt_vision/models/YOLOv5s-seg.yaml +45 -0
  294. mblt_vision/models/YOLOv5s.yaml +44 -0
  295. mblt_vision/models/YOLOv5s6.yaml +50 -0
  296. mblt_vision/models/YOLOv5s6u.yaml +27 -0
  297. mblt_vision/models/YOLOv5su.yaml +27 -0
  298. mblt_vision/models/YOLOv5x-cls.yaml +22 -0
  299. mblt_vision/models/YOLOv5x-seg.yaml +45 -0
  300. mblt_vision/models/YOLOv5x.yaml +44 -0
  301. mblt_vision/models/YOLOv5x6.yaml +50 -0
  302. mblt_vision/models/YOLOv5x6u.yaml +27 -0
  303. mblt_vision/models/YOLOv5xu.yaml +27 -0
  304. mblt_vision/models/YOLOv6m-face.yaml +27 -0
  305. mblt_vision/models/YOLOv6n-face.yaml +27 -0
  306. mblt_vision/models/YOLOv7.yaml +44 -0
  307. mblt_vision/models/YOLOv7d6.yaml +50 -0
  308. mblt_vision/models/YOLOv7e6.yaml +50 -0
  309. mblt_vision/models/YOLOv7e6e.yaml +50 -0
  310. mblt_vision/models/YOLOv7w6.yaml +50 -0
  311. mblt_vision/models/YOLOv7x.yaml +44 -0
  312. mblt_vision/models/YOLOv8l-cls.yaml +23 -0
  313. mblt_vision/models/YOLOv8l-face.yaml +27 -0
  314. mblt_vision/models/YOLOv8l-obb.yaml +28 -0
  315. mblt_vision/models/YOLOv8l-pose.yaml +28 -0
  316. mblt_vision/models/YOLOv8l-seg.yaml +28 -0
  317. mblt_vision/models/YOLOv8l.yaml +27 -0
  318. mblt_vision/models/YOLOv8m-cls.yaml +23 -0
  319. mblt_vision/models/YOLOv8m-face.yaml +27 -0
  320. mblt_vision/models/YOLOv8m-obb.yaml +28 -0
  321. mblt_vision/models/YOLOv8m-pose.yaml +28 -0
  322. mblt_vision/models/YOLOv8m-seg.yaml +28 -0
  323. mblt_vision/models/YOLOv8m.yaml +27 -0
  324. mblt_vision/models/YOLOv8n-cls.yaml +23 -0
  325. mblt_vision/models/YOLOv8n-face.yaml +27 -0
  326. mblt_vision/models/YOLOv8n-obb.yaml +28 -0
  327. mblt_vision/models/YOLOv8n-pose.yaml +28 -0
  328. mblt_vision/models/YOLOv8n-seg.yaml +28 -0
  329. mblt_vision/models/YOLOv8n.yaml +27 -0
  330. mblt_vision/models/YOLOv8s-cls.yaml +23 -0
  331. mblt_vision/models/YOLOv8s-obb.yaml +28 -0
  332. mblt_vision/models/YOLOv8s-pose.yaml +28 -0
  333. mblt_vision/models/YOLOv8s-seg.yaml +28 -0
  334. mblt_vision/models/YOLOv8s.yaml +27 -0
  335. mblt_vision/models/YOLOv8x-cls.yaml +23 -0
  336. mblt_vision/models/YOLOv8x-obb.yaml +28 -0
  337. mblt_vision/models/YOLOv8x-pose-p6.yaml +28 -0
  338. mblt_vision/models/YOLOv8x-pose.yaml +28 -0
  339. mblt_vision/models/YOLOv8x-seg.yaml +28 -0
  340. mblt_vision/models/YOLOv8x.yaml +27 -0
  341. mblt_vision/models/YOLOv9c-seg.yaml +28 -0
  342. mblt_vision/models/YOLOv9c.yaml +27 -0
  343. mblt_vision/models/YOLOv9e-seg.yaml +28 -0
  344. mblt_vision/models/YOLOv9e.yaml +27 -0
  345. mblt_vision/models/YOLOv9m.yaml +27 -0
  346. mblt_vision/models/YOLOv9s.yaml +27 -0
  347. mblt_vision/models/YOLOv9t.yaml +27 -0
  348. mblt_vision/obb/__init__.py +39 -0
  349. mblt_vision/object_detection/__init__.py +153 -0
  350. mblt_vision/pose_estimation/__init__.py +41 -0
  351. mblt_vision/py.typed +1 -0
  352. mblt_vision/semantic_segmentation/__init__.py +29 -0
  353. mblt_vision/utils/__init__.py +0 -0
  354. mblt_vision/utils/datasets/__init__.py +85 -0
  355. mblt_vision/utils/datasets/ade20k.py +41 -0
  356. mblt_vision/utils/datasets/cityscapes.py +66 -0
  357. mblt_vision/utils/datasets/coco.py +243 -0
  358. mblt_vision/utils/datasets/dataloader.py +1016 -0
  359. mblt_vision/utils/datasets/dotav1.py +59 -0
  360. mblt_vision/utils/datasets/imagenet.py +29 -0
  361. mblt_vision/utils/datasets/organizer.py +2145 -0
  362. mblt_vision/utils/datasets/readiness.py +1063 -0
  363. mblt_vision/utils/evaluation/__init__.py +51 -0
  364. mblt_vision/utils/evaluation/_result.py +22 -0
  365. mblt_vision/utils/evaluation/eval_ade20k.py +302 -0
  366. mblt_vision/utils/evaluation/eval_cityscapes.py +32 -0
  367. mblt_vision/utils/evaluation/eval_coco.py +465 -0
  368. mblt_vision/utils/evaluation/eval_dota.py +878 -0
  369. mblt_vision/utils/evaluation/eval_imagenet.py +151 -0
  370. mblt_vision/utils/evaluation/eval_nyu_depth.py +189 -0
  371. mblt_vision/utils/evaluation/eval_widerface.py +440 -0
  372. mblt_vision/utils/letterbox.py +118 -0
  373. mblt_vision/utils/postprocess/__init__.py +9 -0
  374. mblt_vision/utils/postprocess/_letterbox.py +102 -0
  375. mblt_vision/utils/postprocess/base.py +743 -0
  376. mblt_vision/utils/postprocess/build_post.py +120 -0
  377. mblt_vision/utils/postprocess/cls_post.py +117 -0
  378. mblt_vision/utils/postprocess/common.py +1571 -0
  379. mblt_vision/utils/postprocess/depth_post.py +106 -0
  380. mblt_vision/utils/postprocess/semantic_seg_post.py +192 -0
  381. mblt_vision/utils/postprocess/yolo_anchor_post.py +469 -0
  382. mblt_vision/utils/postprocess/yolo_anchorless_post.py +952 -0
  383. mblt_vision/utils/postprocess/yolo_dflfree_post.py +983 -0
  384. mblt_vision/utils/postprocess/yolo_nmsfree_post.py +176 -0
  385. mblt_vision/utils/preprocess/__init__.py +27 -0
  386. mblt_vision/utils/preprocess/_validation.py +66 -0
  387. mblt_vision/utils/preprocess/base.py +157 -0
  388. mblt_vision/utils/preprocess/build_pre.py +48 -0
  389. mblt_vision/utils/preprocess/center_crop.py +75 -0
  390. mblt_vision/utils/preprocess/letterbox.py +123 -0
  391. mblt_vision/utils/preprocess/normalize.py +94 -0
  392. mblt_vision/utils/preprocess/order.py +74 -0
  393. mblt_vision/utils/preprocess/reader.py +94 -0
  394. mblt_vision/utils/preprocess/resize.py +202 -0
  395. mblt_vision/utils/preprocess/yolo_pre.py +7 -0
  396. mblt_vision/utils/results.py +725 -0
  397. mblt_vision/utils/types.py +15 -0
  398. mblt_vision/wrapper.py +1121 -0
  399. mblt_vision_python-0.0.0.dist-info/METADATA +152 -0
  400. mblt_vision_python-0.0.0.dist-info/RECORD +404 -0
  401. mblt_vision_python-0.0.0.dist-info/WHEEL +5 -0
  402. mblt_vision_python-0.0.0.dist-info/entry_points.txt +2 -0
  403. mblt_vision_python-0.0.0.dist-info/licenses/LICENSE +28 -0
  404. mblt_vision_python-0.0.0.dist-info/top_level.txt +1 -0
mblt_vision/wrapper.py ADDED
@@ -0,0 +1,1121 @@
1
+ """
2
+ Wrapper classes for MBLT model execution.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ import copy
8
+ import importlib
9
+ import os
10
+ import stat
11
+ import sys
12
+ import tempfile
13
+ from pathlib import Path
14
+ from types import TracebackType
15
+ from typing import TYPE_CHECKING, Any, Sequence, cast
16
+
17
+ import numpy as np
18
+ import torch
19
+ import yaml
20
+ from huggingface_hub import hf_hub_download
21
+ from huggingface_hub.errors import EntryNotFoundError
22
+
23
+ from mblt_npu import MobilintNPUBackend, ONNXBackend, normalize_target_device
24
+ from ._model_paths import resolve_framework as _resolve_framework
25
+ from ._model_paths import split_model_paths as _split_model_paths
26
+ from ._model_paths import (
27
+ uses_shifted_engine_model_path_layout as _uses_shifted_engine_model_path_layout,
28
+ )
29
+ from .utils.postprocess import build_postprocess
30
+ from .utils.preprocess import build_preprocess
31
+ from .utils.results import Results
32
+ from .utils.types import TensorLike
33
+
34
+ if TYPE_CHECKING:
35
+ from qbruntime import Cluster, CoreId
36
+
37
+ MODEL_CONFIG_DIR = Path(__file__).parent / "models"
38
+
39
+ ONNXRUNTIME_INSTALL_GUIDE = (
40
+ "onnxruntime is not installed. To use ONNX inference, install one of the optional extras:\n"
41
+ "pip install mblt-vision-python[onnxruntime]\n"
42
+ + (
43
+ "or\npip install mblt-vision-python[onnxruntime-gpu]"
44
+ if sys.platform != "darwin"
45
+ else ""
46
+ )
47
+ )
48
+ CoreMode = str
49
+ CORE_MODES: tuple[CoreMode, ...] = ("single", "multi", "global4", "global8")
50
+ REGULUS_TARGET_DEVICES = frozenset({"regulus-ra", "regulus-rb"})
51
+
52
+
53
+ def core_modes_for_target_device(target_device: str) -> tuple[CoreMode, ...]:
54
+ """Return the Vision core modes supported by a normalized NPU board."""
55
+
56
+ if normalize_target_device(target_device) in REGULUS_TARGET_DEVICES:
57
+ return ("single",)
58
+ return CORE_MODES
59
+
60
+
61
+ def normalize_core_mode(
62
+ core_mode: str, *, target_device: str | None = None
63
+ ) -> CoreMode:
64
+ """Validate a Vision engine core mode, including board compatibility."""
65
+
66
+ if core_mode not in CORE_MODES:
67
+ raise ValueError(
68
+ f"Invalid core mode '{core_mode}'. Expected one of {list(CORE_MODES)}."
69
+ )
70
+ if target_device is not None:
71
+ normalized_target_device = normalize_target_device(target_device)
72
+ supported_modes = core_modes_for_target_device(normalized_target_device)
73
+ if core_mode not in supported_modes:
74
+ raise ValueError(
75
+ f"Core mode '{core_mode}' is not supported by "
76
+ f"{normalized_target_device}; expected one of {list(supported_modes)}."
77
+ )
78
+ return core_mode
79
+
80
+
81
+ __all__ = [
82
+ "CoreMode",
83
+ "core_modes_for_target_device",
84
+ "MOBILINT_CACHE_DIR",
85
+ "get_mobilint_cache_dir",
86
+ "normalize_core_mode",
87
+ "resolve_model_config",
88
+ "MBLT_Engine",
89
+ ]
90
+
91
+
92
+ def _derive_onnx_filename(file_cfg: dict[str, Any]) -> str | None:
93
+ """Return the configured or MXQ-derived ONNX artifact filename.
94
+
95
+ ``onnx_filename`` is only required when the Hub ONNX artifact does not share
96
+ the MXQ artifact stem. Otherwise every model configuration follows the same
97
+ ``.mxq`` to ``.onnx`` convention.
98
+ """
99
+
100
+ onnx_filename = file_cfg.get("onnx_filename")
101
+ if isinstance(onnx_filename, str) and onnx_filename:
102
+ return onnx_filename
103
+
104
+ filename = file_cfg.get("filename")
105
+ if not isinstance(filename, str) or not filename:
106
+ return None
107
+
108
+ return f"{Path(filename).stem}.onnx"
109
+
110
+
111
+ def _normalize_model_artifacts(model_config: dict[str, Any]) -> dict[str, Any]:
112
+ """Populate the derived ONNX artifact name in a resolved model configuration."""
113
+
114
+ normalized = copy.deepcopy(model_config)
115
+ file_cfg = normalized.get("file_cfg")
116
+ if not isinstance(file_cfg, dict):
117
+ return normalized
118
+
119
+ onnx_filename = _derive_onnx_filename(file_cfg)
120
+ if onnx_filename is not None:
121
+ file_cfg["onnx_filename"] = onnx_filename
122
+ return normalized
123
+
124
+
125
+ def _default_cache_dir() -> str:
126
+ """Returns a writable cache directory for downloaded vision artifacts."""
127
+
128
+ preferred = Path(os.path.expanduser("~/.mblt_model_zoo"))
129
+ try:
130
+ preferred.mkdir(parents=True, mode=0o700, exist_ok=True)
131
+ preferred_stat = os.lstat(preferred)
132
+ if (
133
+ not stat.S_ISDIR(preferred_stat.st_mode)
134
+ or stat.S_ISLNK(preferred_stat.st_mode)
135
+ or preferred_stat.st_uid != os.getuid()
136
+ or preferred_stat.st_mode & 0o077
137
+ ):
138
+ return _fallback_cache_dir()
139
+ with tempfile.NamedTemporaryFile(prefix=".write_test-", dir=preferred):
140
+ pass
141
+ return str(preferred)
142
+ except OSError:
143
+ return _fallback_cache_dir()
144
+
145
+
146
+ def _fallback_cache_dir() -> str:
147
+ """Return a stable private fallback cache when the home cache is unavailable."""
148
+
149
+ uid = os.getuid()
150
+ fallback = Path(tempfile.gettempdir()) / f"mblt_model_zoo-{uid}"
151
+ try:
152
+ os.mkdir(fallback, mode=0o700)
153
+ except FileExistsError:
154
+ pass
155
+ except OSError as exc:
156
+ raise RuntimeError(
157
+ f"Unable to create fallback Mobilint cache directory: {fallback}"
158
+ ) from exc
159
+
160
+ fallback_stat = os.lstat(fallback)
161
+ if (
162
+ not stat.S_ISDIR(fallback_stat.st_mode)
163
+ or stat.S_ISLNK(fallback_stat.st_mode)
164
+ or fallback_stat.st_uid != uid
165
+ or fallback_stat.st_mode & 0o077
166
+ ):
167
+ raise RuntimeError(
168
+ f"Fallback Mobilint cache directory is not a private directory owned by this user: {fallback}"
169
+ )
170
+
171
+ try:
172
+ with tempfile.NamedTemporaryFile(prefix=".write_test-", dir=fallback):
173
+ pass
174
+ except OSError as exc:
175
+ raise RuntimeError(
176
+ f"Fallback Mobilint cache directory is not writable: {fallback}"
177
+ ) from exc
178
+ return str(fallback)
179
+
180
+
181
+ MOBILINT_CACHE_DIR = os.path.expanduser("~/.mblt_model_zoo")
182
+ """Preferred artifact cache root, without creating it during import."""
183
+
184
+ _resolved_cache_dir: str | None = None
185
+
186
+
187
+ def get_mobilint_cache_dir() -> str:
188
+ """Return a writable artifact cache directory, creating it only when needed."""
189
+
190
+ global _resolved_cache_dir
191
+ if _resolved_cache_dir is None:
192
+ _resolved_cache_dir = _default_cache_dir()
193
+ return _resolved_cache_dir
194
+
195
+
196
+ def _load_onnxruntime() -> Any:
197
+ """Loads ``onnxruntime`` only when ONNX inference is requested.
198
+
199
+ Returns:
200
+ The imported ``onnxruntime`` module.
201
+
202
+ Raises:
203
+ ImportError: If ``onnxruntime`` is unavailable in the current environment.
204
+ """
205
+
206
+ try:
207
+ module = importlib.import_module("onnxruntime")
208
+ except ImportError as exc:
209
+ raise ImportError(ONNXRUNTIME_INSTALL_GUIDE) from exc
210
+
211
+ if not hasattr(module, "InferenceSession"):
212
+ module_path = getattr(module, "__file__", None) or "<namespace package>"
213
+ msg = (
214
+ "onnxruntime is installed, but the package is incomplete or broken and does not expose "
215
+ f"`InferenceSession` (resolved from {module_path}). "
216
+ f"{ONNXRUNTIME_INSTALL_GUIDE.replace('is not installed. To use ONNX inference, install', 'Reinstall')}"
217
+ )
218
+ raise ImportError(msg)
219
+
220
+ return module
221
+
222
+
223
+ def _resolve_onnx_providers(
224
+ ort_module: Any, requested_providers: Sequence[str] | None = None
225
+ ) -> list[str]:
226
+ """Selects ONNX Runtime execution providers.
227
+
228
+ Args:
229
+ ort_module: Imported ``onnxruntime`` module or compatible test double.
230
+ requested_providers: Optional provider order requested by the caller.
231
+
232
+ Returns:
233
+ The provider list passed to ``InferenceSession``.
234
+ """
235
+
236
+ return (
237
+ list(requested_providers)
238
+ if requested_providers is not None
239
+ else ["CPUExecutionProvider"]
240
+ )
241
+
242
+
243
+ def _model_name_aliasing(model_name: str) -> str:
244
+ """Find the YAML filename matching a model name.
245
+
246
+ Args:
247
+ model_name: Model identifier provided by the caller.
248
+
249
+ Returns:
250
+ Exact YAML filename stored in ``MODEL_CONFIG_DIR``.
251
+
252
+ Raises:
253
+ ValueError: If no YAML file matches or the normalized name is ambiguous.
254
+ """
255
+
256
+ def _stem(name: str) -> str:
257
+ return name[: -len(".yaml")] if name.lower().endswith(".yaml") else name
258
+
259
+ def _normalize_separators(name: str) -> str:
260
+ return "_".join(
261
+ part
262
+ for part in _stem(name)
263
+ .replace("-", "_")
264
+ .replace(" ", "_")
265
+ .lower()
266
+ .split("_")
267
+ if part
268
+ )
269
+
270
+ requested = _normalize_separators(model_name)
271
+ config_names = sorted(path.name for path in MODEL_CONFIG_DIR.glob("*.yaml"))
272
+ separator_matches = [
273
+ name for name in config_names if _normalize_separators(name) == requested
274
+ ]
275
+ if len(separator_matches) == 1:
276
+ return separator_matches[0]
277
+ if len(separator_matches) > 1:
278
+ raise ValueError(
279
+ f"Ambiguous model name '{model_name}'. Matches: {separator_matches}."
280
+ )
281
+
282
+ compact_requested = requested.replace("_", "")
283
+ compact_matches = [
284
+ name
285
+ for name in config_names
286
+ if _normalize_separators(name).replace("_", "") == compact_requested
287
+ ]
288
+ if len(compact_matches) == 1:
289
+ return compact_matches[0]
290
+ if len(compact_matches) > 1:
291
+ raise ValueError(
292
+ f"Ambiguous model name '{model_name}'. Matches: {compact_matches}."
293
+ )
294
+ raise ValueError(f"Model name '{model_name}' is not supported.")
295
+
296
+
297
+ def resolve_model_config(
298
+ model_cls: str | dict[str, Any], model_type: str = "DEFAULT"
299
+ ) -> dict[str, Any]:
300
+ """Resolve a vision model configuration without constructing a runtime.
301
+
302
+ Args:
303
+ model_cls: Model name, YAML path, or direct model configuration.
304
+ model_type: Variant key within a YAML model definition.
305
+
306
+ Returns:
307
+ A deep copy of the resolved ``file_cfg``, ``pre_cfg``, and ``post_cfg`` mapping.
308
+ ``file_cfg`` always includes an ONNX filename when an MXQ filename is available.
309
+
310
+ Raises:
311
+ TypeError: If the YAML or resolved configuration is not a mapping.
312
+ ValueError: If a requested variant, alias, or update base is unavailable.
313
+ """
314
+
315
+ if isinstance(model_cls, dict):
316
+ return _normalize_model_artifacts(model_cls)
317
+
318
+ config_path = Path(model_cls)
319
+ if not config_path.is_file():
320
+ config_path = MODEL_CONFIG_DIR / _model_name_aliasing(model_cls)
321
+
322
+ with config_path.open(encoding="utf-8") as config_file:
323
+ full_config = yaml.safe_load(config_file)
324
+ if not isinstance(full_config, dict):
325
+ raise TypeError(
326
+ f"Model configuration '{config_path}' should define a dictionary."
327
+ )
328
+
329
+ resolving: set[str] = set()
330
+
331
+ def _resolve_variant(variant: str) -> dict[str, Any]:
332
+ if variant in resolving:
333
+ raise ValueError(
334
+ f"Circular model configuration reference detected for '{variant}'."
335
+ )
336
+ resolving.add(variant)
337
+ try:
338
+ model_config_part = full_config.get(variant)
339
+ if model_config_part is None:
340
+ raise ValueError(f"Model type '{variant}' not found in configuration.")
341
+ if isinstance(model_config_part, str):
342
+ if model_config_part not in full_config:
343
+ raise ValueError(
344
+ f"Model alias '{model_config_part}' not found in configuration."
345
+ )
346
+ return _resolve_variant(model_config_part)
347
+ if not isinstance(model_config_part, dict):
348
+ raise TypeError(
349
+ f"Resolved model configuration for '{variant}' is not a dictionary."
350
+ )
351
+
352
+ resolved = copy.deepcopy(model_config_part)
353
+ base_config_key = resolved.pop("update", None)
354
+ if base_config_key is None:
355
+ return resolved
356
+ if (
357
+ not isinstance(base_config_key, str)
358
+ or base_config_key not in full_config
359
+ ):
360
+ raise ValueError(
361
+ f"Base configuration '{base_config_key}' not found for update."
362
+ )
363
+
364
+ merged_config = _resolve_variant(base_config_key)
365
+ for key, value in resolved.items():
366
+ if (
367
+ key in merged_config
368
+ and isinstance(merged_config[key], dict)
369
+ and isinstance(value, dict)
370
+ ):
371
+ merged_config[key].update(value)
372
+ else:
373
+ merged_config[key] = value
374
+ return merged_config
375
+ finally:
376
+ resolving.remove(variant)
377
+
378
+ return _normalize_model_artifacts(_resolve_variant(model_type))
379
+
380
+
381
+ class MBLT_Engine:
382
+ """Main engine class for running vision models from the MBLT zoo.
383
+
384
+ Handles the full pipeline: Preprocessing -> Inference -> Postprocessing.
385
+
386
+ Attributes:
387
+ file_cfg: Model configuration.
388
+ pre_cfg: Preprocessing configuration.
389
+ post_cfg: Postprocessing configuration.
390
+ model: The underlying MXQ_Model.
391
+ device: The torch device being used.
392
+ """
393
+
394
+ def __init__(
395
+ self,
396
+ model_cls: str | dict[str, Any],
397
+ model_type: str = "DEFAULT",
398
+ mxq_path: str = "",
399
+ onnx_path: str = "",
400
+ dev_no: int | None = None,
401
+ core_mode: CoreMode | None = None,
402
+ target_cores: Sequence[str | CoreId] | None = None,
403
+ target_clusters: Sequence[int | Cluster] | None = None,
404
+ postprocess_kwargs: dict[str, Any] | None = None,
405
+ framework: str | None = None,
406
+ onnx_providers: Sequence[str] | None = None,
407
+ model_path: str = "",
408
+ target_device: str | None = None,
409
+ ) -> None:
410
+ """Initializes the MBLT_Engine.
411
+
412
+ Args:
413
+ model_cls(if dict):
414
+ file_cfg: Model configuration.
415
+ mxq_path: path to mxq file
416
+ onnx_path: path to onnx file
417
+ model_path: generic path to local model file
418
+ dev_no: Accelerator No.
419
+ core_mode: single, multi, global4, global8
420
+ target_cores: single mode
421
+ target_clusters: multi, global modes
422
+ target_device: NPU board identifier; defaults to ``aries-rb``.
423
+ pre_cfg: Preprocessing configuration.
424
+ post_cfg: Postprocessing configuration.
425
+ model_cls(not dict): model name or yaml path
426
+ postprocess_kwargs: Optional runtime overrides passed to the postprocessor builder.
427
+ framework: Execution framework, either "mxq" or "onnx". When omitted,
428
+ ``model_path`` suffix is used first, then MXQ is the fallback.
429
+ onnx_providers: Optional ONNX Runtime execution provider order.
430
+ target_device: NPU board identifier. An explicit value takes precedence
431
+ over ``file_cfg.target_device``; otherwise defaults to ``aries-rb``.
432
+ """
433
+
434
+ if _uses_shifted_engine_model_path_layout(
435
+ model_path,
436
+ mxq_path,
437
+ dev_no,
438
+ core_mode,
439
+ target_cores,
440
+ postprocess_kwargs,
441
+ framework,
442
+ onnx_providers,
443
+ ):
444
+ (
445
+ model_path,
446
+ mxq_path,
447
+ onnx_path,
448
+ dev_no,
449
+ core_mode,
450
+ target_cores,
451
+ target_clusters,
452
+ postprocess_kwargs,
453
+ framework,
454
+ onnx_providers,
455
+ ) = (
456
+ mxq_path,
457
+ onnx_path,
458
+ cast(str, dev_no or ""),
459
+ cast(int | None, core_mode),
460
+ cast(CoreMode | None, target_cores),
461
+ cast(Sequence[str | Any] | None, target_clusters),
462
+ cast(Sequence[int | Any] | None, postprocess_kwargs),
463
+ cast(dict[str, Any] | None, framework),
464
+ cast(str | None, onnx_providers),
465
+ cast(Sequence[str] | None, model_path or None),
466
+ )
467
+ model_config_part = resolve_model_config(model_cls, model_type)
468
+ for section in ("file_cfg", "pre_cfg", "post_cfg"):
469
+ if not isinstance(model_config_part.get(section), dict):
470
+ raise ValueError(
471
+ f"Model configuration section '{section}' must be a mapping."
472
+ )
473
+
474
+ if mxq_path and Path(mxq_path).suffix.lower() != ".mxq":
475
+ raise ValueError(f"Explicit mxq_path must end in '.mxq', got {mxq_path!r}.")
476
+ if onnx_path and Path(onnx_path).suffix.lower() != ".onnx":
477
+ raise ValueError(
478
+ f"Explicit onnx_path must end in '.onnx', got {onnx_path!r}."
479
+ )
480
+ for key, suffix in (("mxq_path", ".mxq"), ("onnx_path", ".onnx")):
481
+ configured_path = model_config_part["file_cfg"].get(key)
482
+ if configured_path and (
483
+ not isinstance(configured_path, str)
484
+ or Path(configured_path).suffix.lower() != suffix
485
+ ):
486
+ raise ValueError(
487
+ f"Configured file_cfg.{key} must end in {suffix!r}, "
488
+ f"got {configured_path!r}."
489
+ )
490
+
491
+ file_cfg_model_path = str(model_config_part["file_cfg"].get("model_path", ""))
492
+ file_cfg_onnx_path = str(model_config_part["file_cfg"].get("onnx_path", ""))
493
+ framework_model_path = model_path or file_cfg_model_path
494
+ if not framework_model_path and not mxq_path:
495
+ framework_model_path = onnx_path or file_cfg_onnx_path
496
+ self.framework = _resolve_framework(framework, framework_model_path)
497
+ mxq_path, onnx_path = _split_model_paths(
498
+ framework=self.framework,
499
+ model_path=model_path,
500
+ mxq_path=mxq_path,
501
+ onnx_path=onnx_path,
502
+ )
503
+
504
+ _mxq_path_passed = bool(mxq_path)
505
+ _onnx_path_passed = bool(onnx_path)
506
+ if _mxq_path_passed and not os.path.isfile(mxq_path):
507
+ raise FileNotFoundError(
508
+ "Explicit MXQ model path does not exist: "
509
+ f"{mxq_path}. Remove model_path/mxq_path to download the configured artifact."
510
+ )
511
+ if _onnx_path_passed and not os.path.isfile(onnx_path):
512
+ raise FileNotFoundError(
513
+ "Explicit ONNX model path does not exist: "
514
+ f"{onnx_path}. Remove model_path/onnx_path to download the configured artifact."
515
+ )
516
+ _dev_no_passed = dev_no is not None
517
+ _core_mode_passed = core_mode is not None
518
+ _target_cores_passed = target_cores is not None
519
+ _target_clusters_passed = target_clusters is not None
520
+
521
+ if dev_no is None:
522
+ dev_no = 0
523
+ if target_device is None:
524
+ target_device = model_config_part["file_cfg"].get(
525
+ "target_device", "aries-rb"
526
+ )
527
+ target_device = normalize_target_device(target_device)
528
+ is_regulus = target_device in {"regulus-ra", "regulus-rb"}
529
+ if core_mode is None:
530
+ core_mode = "single" if is_regulus else "global8"
531
+ else:
532
+ core_mode = normalize_core_mode(core_mode, target_device=target_device)
533
+ if target_cores is None:
534
+ target_cores = (
535
+ []
536
+ if is_regulus
537
+ else ["0:0", "0:1", "0:2", "0:3", "1:0", "1:1", "1:2", "1:3"]
538
+ )
539
+ if target_clusters is None:
540
+ target_clusters = [] if is_regulus else [0, 1]
541
+
542
+ self.file_cfg = copy.deepcopy(model_config_part["file_cfg"])
543
+ file_cfg_model_path = self.file_cfg.pop("model_path", "")
544
+ if file_cfg_model_path:
545
+ yaml_mxq_path, yaml_onnx_path = _split_model_paths(
546
+ framework=self.framework,
547
+ model_path=file_cfg_model_path,
548
+ mxq_path=str(self.file_cfg.get("mxq_path", "")),
549
+ onnx_path=str(self.file_cfg.get("onnx_path", "")),
550
+ )
551
+ self.file_cfg["mxq_path"] = yaml_mxq_path
552
+ self.file_cfg["onnx_path"] = yaml_onnx_path
553
+ if _mxq_path_passed or "mxq_path" not in self.file_cfg:
554
+ self.file_cfg["mxq_path"] = mxq_path
555
+ if _onnx_path_passed or "onnx_path" not in self.file_cfg:
556
+ self.file_cfg["onnx_path"] = onnx_path
557
+ if _core_mode_passed or "core_mode" not in self.file_cfg or is_regulus:
558
+ self.file_cfg["core_mode"] = core_mode
559
+ if _target_cores_passed or "target_cores" not in self.file_cfg:
560
+ self.file_cfg["target_cores"] = target_cores
561
+ if _target_clusters_passed or "target_clusters" not in self.file_cfg:
562
+ self.file_cfg["target_clusters"] = target_clusters
563
+ if _dev_no_passed or "dev_no" not in self.file_cfg:
564
+ self.file_cfg["dev_no"] = dev_no
565
+ self.file_cfg["core_mode"] = normalize_core_mode(
566
+ self.file_cfg["core_mode"], target_device=target_device
567
+ )
568
+ self.file_cfg["target_device"] = target_device
569
+
570
+ self.pre_cfg = copy.deepcopy(model_config_part["pre_cfg"])
571
+ self.post_cfg = copy.deepcopy(model_config_part["post_cfg"])
572
+ self.postprocess_kwargs = (
573
+ {} if postprocess_kwargs is None else dict(postprocess_kwargs)
574
+ )
575
+ self.file_config_cleansing()
576
+
577
+ self.model: Any
578
+ self._mxq_model: MobilintNPUBackend | None = None
579
+ self._onnx_model: ONNXBackend | None = None
580
+ self._onnx_session: Any = None
581
+ self._closed = False
582
+
583
+ try:
584
+ if self.framework == "onnx":
585
+ ort = _load_onnxruntime()
586
+ resolved_onnx_path = self.file_cfg.get("onnx_path")
587
+ if not resolved_onnx_path:
588
+ raise RuntimeError(
589
+ f"ONNX path not resolved for model {model_cls}. Make sure the model repository has an ONNX file."
590
+ )
591
+ if not os.path.isfile(resolved_onnx_path):
592
+ raise FileNotFoundError(
593
+ f"ONNX file not found at: {resolved_onnx_path}"
594
+ )
595
+
596
+ providers = _resolve_onnx_providers(ort, onnx_providers)
597
+ onnx_model = ONNXBackend(
598
+ resolved_onnx_path, providers=providers, ort_module=ort
599
+ )
600
+ self._onnx_model = onnx_model
601
+ onnx_model.create()
602
+ self._onnx_session = onnx_model.session
603
+ self.model = self._onnx_session
604
+ onnx_inputs = self._onnx_session.get_inputs()
605
+ if len(onnx_inputs) != 1:
606
+ raise ValueError(
607
+ "ONNX models must declare exactly one input because "
608
+ "MBLT_Engine accepts one preprocessed tensor; got "
609
+ f"{len(onnx_inputs)} inputs."
610
+ )
611
+ self.input_name = onnx_inputs[0].name
612
+ self.output_names = [o.name for o in self._onnx_session.get_outputs()]
613
+ else:
614
+ mxq_model = MobilintNPUBackend(**self._mxq_backend_kwargs())
615
+ self._mxq_model = mxq_model
616
+ self.model = mxq_model
617
+ mxq_model.create()
618
+ mxq_model.launch()
619
+
620
+ if mxq_model.get_dtype() == "DataType.Uint8":
621
+ self.pre_cfg.pop("Normalize", None)
622
+
623
+ self.preprocessor = build_preprocess(self.pre_cfg)
624
+ self.postprocessor = build_postprocess(
625
+ self.pre_cfg, self.post_cfg, **self.postprocess_kwargs
626
+ )
627
+ self.device = torch.device("cpu")
628
+ except Exception:
629
+ self._close(suppress_errors=True)
630
+ raise
631
+
632
+ def _mxq_backend_kwargs(self) -> dict[str, Any]:
633
+ """Builds the MXQ backend kwargs from the resolved file config."""
634
+
635
+ excluded_keys = {
636
+ "repo_id",
637
+ "filename",
638
+ "revision",
639
+ "onnx_filename",
640
+ "onnx_path",
641
+ }
642
+ return {
643
+ key: value
644
+ for key, value in self.file_cfg.items()
645
+ if key not in excluded_keys
646
+ }
647
+
648
+ def _derive_onnx_filename(self) -> str | None:
649
+ """Returns the ONNX filename associated with the configured MXQ artifact."""
650
+
651
+ onnx_filename = _derive_onnx_filename(self.file_cfg)
652
+ if onnx_filename is not None:
653
+ self.file_cfg["onnx_filename"] = onnx_filename
654
+ return onnx_filename
655
+
656
+ def _resolve_local_onnx_path(self, mxq_path: str) -> str | None:
657
+ """Tries to resolve a sibling ONNX file next to a local MXQ artifact."""
658
+
659
+ onnx_path = self.file_cfg.get("onnx_path", "")
660
+ if onnx_path and os.path.isfile(onnx_path):
661
+ return onnx_path
662
+
663
+ onnx_filename = self._derive_onnx_filename()
664
+ if onnx_filename:
665
+ sibling_path = Path(mxq_path).with_name(onnx_filename)
666
+ if sibling_path.is_file():
667
+ return str(sibling_path)
668
+
669
+ if mxq_path.endswith(".mxq"):
670
+ suffix_swapped = f"{mxq_path[:-4]}.onnx"
671
+ if os.path.isfile(suffix_swapped):
672
+ return suffix_swapped
673
+
674
+ return None
675
+
676
+ def _download_hub_artifact(
677
+ self,
678
+ *,
679
+ repo_id: str,
680
+ filename: str,
681
+ revision: str,
682
+ subfolders: Sequence[str] | None = None,
683
+ ) -> str:
684
+ """Downloads a model artifact from Hugging Face Hub and returns its cache path."""
685
+
686
+ last_error: Exception | None = None
687
+ normalized_subfolders = [""] if subfolders is None else list(subfolders)
688
+ for subfolder in normalized_subfolders:
689
+ kwargs: dict[str, Any] = {
690
+ "repo_id": repo_id,
691
+ "filename": filename,
692
+ "revision": revision,
693
+ "local_dir": get_mobilint_cache_dir(),
694
+ }
695
+ if subfolder:
696
+ kwargs["subfolder"] = subfolder
697
+ try:
698
+ return hf_hub_download(**kwargs)
699
+ except EntryNotFoundError as exc:
700
+ last_error = exc
701
+
702
+ attempted_paths = ", ".join(
703
+ f"{subfolder}/{filename}" if subfolder else filename
704
+ for subfolder in normalized_subfolders
705
+ )
706
+ raise RuntimeError(
707
+ f"Failed to download model from Hugging Face. Tried repo '{repo_id}' at: {attempted_paths}."
708
+ ) from last_error
709
+
710
+ def file_config_cleansing(self) -> None:
711
+ """Validates and resolves the MXQ and ONNX model file paths in ``self.file_cfg``."""
712
+ framework = getattr(self, "framework", "mxq")
713
+ model_path = self.file_cfg.pop("model_path", "")
714
+ if model_path:
715
+ mxq_path, onnx_path = _split_model_paths(
716
+ framework=framework,
717
+ model_path=model_path,
718
+ mxq_path=str(self.file_cfg.get("mxq_path", "")),
719
+ onnx_path=str(self.file_cfg.get("onnx_path", "")),
720
+ )
721
+ self.file_cfg["mxq_path"] = mxq_path
722
+ self.file_cfg["onnx_path"] = onnx_path
723
+ mxq_path = self.file_cfg.get("mxq_path", "")
724
+ onnx_path = self.file_cfg.get("onnx_path", "")
725
+ onnx_filename = self._derive_onnx_filename()
726
+
727
+ if onnx_path and os.path.isfile(onnx_path):
728
+ self.file_cfg["onnx_path"] = onnx_path
729
+ if framework == "onnx":
730
+ return
731
+
732
+ if mxq_path and os.path.isfile(mxq_path):
733
+ resolved_local_onnx = self._resolve_local_onnx_path(mxq_path)
734
+ if resolved_local_onnx is not None:
735
+ self.file_cfg["onnx_path"] = resolved_local_onnx
736
+ self.file_cfg.pop("repo_id", None)
737
+ self.file_cfg.pop("filename", None)
738
+ self.file_cfg.pop("revision", None)
739
+ elif framework == "mxq":
740
+ self.file_cfg.pop("repo_id", None)
741
+ self.file_cfg.pop("filename", None)
742
+ self.file_cfg.pop("revision", None)
743
+ if framework == "mxq":
744
+ return
745
+
746
+ repo_id = self.file_cfg.pop("repo_id", None)
747
+ filename = self.file_cfg.pop("filename", None)
748
+ revision = self.file_cfg.pop("revision", None)
749
+ if not repo_id or not revision:
750
+ return
751
+
752
+ if filename and framework == "mxq":
753
+ target_device = self.file_cfg.get("target_device", "aries-rb")
754
+ self.file_cfg["mxq_path"] = self._download_hub_artifact(
755
+ repo_id=repo_id,
756
+ filename=filename,
757
+ revision=revision,
758
+ subfolders=[target_device],
759
+ )
760
+
761
+ if onnx_filename and framework == "onnx" and not self.file_cfg.get("onnx_path"):
762
+ self.file_cfg["onnx_path"] = self._download_hub_artifact(
763
+ repo_id=repo_id,
764
+ filename=onnx_filename,
765
+ revision=revision,
766
+ )
767
+
768
+ def _prepare_onnx_inputs(self, x: TensorLike) -> dict[str, np.ndarray]:
769
+ """Normalizes runtime inputs to match the ONNX session contract."""
770
+
771
+ if isinstance(x, torch.Tensor):
772
+ x_np = x.detach().cpu().numpy()
773
+ elif isinstance(x, np.ndarray):
774
+ x_np = x
775
+ else:
776
+ raise TypeError(f"Got unexpected type for ONNX input x={type(x)}.")
777
+
778
+ if x_np.dtype == np.float64:
779
+ x_np = x_np.astype(np.float32)
780
+
781
+ expected_shape = self._require_onnx_session().get_inputs()[0].shape
782
+ if len(expected_shape) == 4:
783
+ expected_second_dim = expected_shape[1]
784
+ expected_last_dim = expected_shape[-1]
785
+ expected_layout = None
786
+ expected_channels = None
787
+ # ONNX layout is encoded by the channel axis, not by a spatial
788
+ # dimension that happens to equal a channel count. This is crucial
789
+ # for square static inputs such as [1, 3, 224, 224].
790
+ if isinstance(expected_second_dim, int) and expected_second_dim in {
791
+ 1,
792
+ 2,
793
+ 3,
794
+ 4,
795
+ }:
796
+ expected_layout = "nchw"
797
+ expected_channels = expected_second_dim
798
+ elif isinstance(expected_last_dim, int) and expected_last_dim in {
799
+ 1,
800
+ 2,
801
+ 3,
802
+ 4,
803
+ }:
804
+ expected_layout = "nhwc"
805
+ expected_channels = expected_last_dim
806
+
807
+ if x_np.ndim == 3:
808
+ if (
809
+ expected_layout == "nchw"
810
+ and expected_channels is not None
811
+ and x_np.shape[0] == expected_channels
812
+ ):
813
+ x_np = np.expand_dims(x_np, axis=0)
814
+ elif (
815
+ expected_layout == "nchw"
816
+ and expected_channels is not None
817
+ and x_np.shape[-1] == expected_channels
818
+ ):
819
+ x_np = np.transpose(x_np, (2, 0, 1))
820
+ x_np = np.expand_dims(x_np, axis=0)
821
+ elif (
822
+ expected_layout == "nhwc"
823
+ and expected_channels is not None
824
+ and x_np.shape[-1] == expected_channels
825
+ ):
826
+ x_np = np.expand_dims(x_np, axis=0)
827
+ elif (
828
+ expected_layout == "nhwc"
829
+ and expected_channels is not None
830
+ and x_np.shape[0] == expected_channels
831
+ ):
832
+ x_np = np.transpose(x_np, (1, 2, 0))
833
+ x_np = np.expand_dims(x_np, axis=0)
834
+ elif x_np.ndim == 4:
835
+ if expected_layout == "nchw" and expected_channels is not None:
836
+ if x_np.shape[1] == expected_channels:
837
+ pass
838
+ elif x_np.shape[-1] == expected_channels:
839
+ x_np = np.transpose(x_np, (0, 3, 1, 2))
840
+ elif expected_layout == "nhwc" and expected_channels is not None:
841
+ if x_np.shape[-1] == expected_channels:
842
+ pass
843
+ elif x_np.shape[1] == expected_channels:
844
+ x_np = np.transpose(x_np, (0, 2, 3, 1))
845
+
846
+ return {self.input_name: x_np}
847
+
848
+ def _require_onnx_session(self) -> Any:
849
+ """Return the active ONNX session."""
850
+
851
+ session = getattr(self, "_onnx_session", None)
852
+ if session is None:
853
+ fallback = getattr(self, "model", None)
854
+ if (
855
+ fallback is not None
856
+ and hasattr(fallback, "get_inputs")
857
+ and hasattr(fallback, "run")
858
+ ):
859
+ return fallback
860
+ raise RuntimeError("ONNX session is not initialized.")
861
+ return session
862
+
863
+ def _require_mxq_model(self) -> MobilintNPUBackend:
864
+ """Return the active MXQ backend."""
865
+
866
+ model = getattr(self, "_mxq_model", None)
867
+ if model is None:
868
+ fallback = getattr(self, "model", None)
869
+ if (
870
+ fallback is not None
871
+ and hasattr(fallback, "create")
872
+ and hasattr(fallback, "launch")
873
+ ):
874
+ return cast(MobilintNPUBackend, fallback)
875
+ raise RuntimeError("MXQ backend is not initialized.")
876
+ return model
877
+
878
+ def __call__(
879
+ self,
880
+ x: TensorLike,
881
+ ) -> Any:
882
+ """Runs raw model inference on the input.
883
+
884
+ Note:
885
+ This does NOT include preprocessing or postprocessing.
886
+
887
+ Args:
888
+ x: Input tensor for the model.
889
+
890
+ Returns:
891
+ Raw model output.
892
+ """
893
+ self._ensure_open()
894
+ if self.framework == "onnx":
895
+ outputs = self._require_onnx_session().run(
896
+ self.output_names, self._prepare_onnx_inputs(x)
897
+ )
898
+ if len(outputs) == 1:
899
+ return outputs[0]
900
+ return outputs
901
+ return cast(Any, self._require_mxq_model())(x)
902
+
903
+ def preprocess(
904
+ self,
905
+ x: Any,
906
+ **kwargs: Any,
907
+ ) -> Any:
908
+ """Runs preprocessing on the input.
909
+
910
+ Args:
911
+ x: Input data.
912
+ **kwargs: Additional arguments for preprocessing.
913
+
914
+ Returns:
915
+ Preprocessed data.
916
+ """
917
+ return self.preprocessor(x, **kwargs)
918
+
919
+ def preprocess_with_metadata(
920
+ self,
921
+ x: Any,
922
+ ) -> tuple[Any, dict[str, Any]]:
923
+ """Runs preprocessing and returns metadata needed for exact postprocess scaling.
924
+
925
+ Args:
926
+ x: Input data.
927
+
928
+ Returns:
929
+ A tuple of preprocessed data and metadata such as ``ratio_pad``.
930
+ """
931
+ return self.preprocessor.with_metadata(x)
932
+
933
+ def postprocess(
934
+ self,
935
+ x: Any,
936
+ **kwargs: Any,
937
+ ) -> Results:
938
+ """Runs postprocessing on the input.
939
+
940
+ Args:
941
+ x: Input data.
942
+ **kwargs: Additional arguments for postprocessing.
943
+
944
+ Returns:
945
+ Postprocessed results.
946
+ """
947
+ pre_result = self.postprocessor(x, **kwargs)
948
+ result_kwargs = dict(kwargs)
949
+ conf_thres = getattr(self.postprocessor, "conf_thres", None)
950
+ iou_thres = getattr(self.postprocessor, "iou_thres", None)
951
+ if "conf_thres" not in result_kwargs and conf_thres is not None:
952
+ result_kwargs["conf_thres"] = conf_thres
953
+ if "iou_thres" not in result_kwargs and iou_thres is not None:
954
+ result_kwargs["iou_thres"] = iou_thres
955
+ return Results(self.pre_cfg, self.post_cfg, pre_result, **result_kwargs)
956
+
957
+ def set_postprocess_thresholds(
958
+ self, conf_thres: float | None = None, iou_thres: float | None = None
959
+ ) -> None:
960
+ """Updates configurable postprocess thresholds for the current model.
961
+
962
+ Args:
963
+ conf_thres: Optional confidence threshold override.
964
+ iou_thres: Optional IoU threshold override.
965
+
966
+ Raises:
967
+ NotImplementedError: If the current postprocessor does not support thresholds.
968
+ """
969
+ set_threshold = getattr(self.postprocessor, "set_threshold", None)
970
+ if set_threshold is None:
971
+ raise NotImplementedError(
972
+ f"Threshold overrides are not supported for task `{self.post_cfg.get('task', 'unknown')}`."
973
+ )
974
+ set_threshold(conf_thres=conf_thres, iou_thres=iou_thres)
975
+
976
+ def to(
977
+ self,
978
+ device: str | torch.device,
979
+ ) -> None:
980
+ """Moves the engine and its components to the specified device.
981
+
982
+ Args:
983
+ device: Target device.
984
+
985
+ Raises:
986
+ TypeError: If device type is unexpected.
987
+ """
988
+ self.preprocessor.to(device)
989
+ self.postprocessor.to(device)
990
+
991
+ if isinstance(device, str):
992
+ self.device = torch.device(device)
993
+ elif isinstance(device, torch.device):
994
+ self.device = device
995
+ else:
996
+ raise TypeError(f"Got unexpected type for device={type(device)}.")
997
+
998
+ def cpu(self) -> None:
999
+ """Moves the engine to CPU."""
1000
+ self.to(device="cpu")
1001
+
1002
+ def gpu(self) -> None:
1003
+ """Moves the engine to GPU (CUDA)."""
1004
+ self.to(device="cuda")
1005
+
1006
+ def cuda(
1007
+ self,
1008
+ device: str | int = 0,
1009
+ ) -> None:
1010
+ """Moves the engine to CUDA device.
1011
+
1012
+ Args:
1013
+ device: CUDA device identifier. Defaults to 0.
1014
+
1015
+ Raises:
1016
+ ValueError: If device string is invalid.
1017
+ RuntimeError: If CUDA is not available.
1018
+ """
1019
+ if isinstance(device, int):
1020
+ device = f"cuda:{device}"
1021
+ elif isinstance(device, str):
1022
+ if not device.startswith("cuda:"):
1023
+ raise ValueError("Invalid device string. It should start with 'cuda:'.")
1024
+
1025
+ if not torch.cuda.is_available():
1026
+ raise RuntimeError("CUDA is not available. Please check your environment.")
1027
+ self.to(device=device)
1028
+
1029
+ def launch(self) -> None:
1030
+ """Launches the underlying model."""
1031
+ self._ensure_open()
1032
+ if self.framework == "mxq":
1033
+ self._require_mxq_model().launch()
1034
+
1035
+ def dispose(self) -> None:
1036
+ """Compatibility alias for :meth:`close`."""
1037
+
1038
+ self.close()
1039
+
1040
+ def close(self) -> None:
1041
+ """Release backend resources. Safe to call more than once."""
1042
+
1043
+ self._close(suppress_errors=False)
1044
+
1045
+ def __enter__(self) -> MBLT_Engine:
1046
+ """Return this engine for use in a context manager."""
1047
+
1048
+ self._ensure_open()
1049
+ return self
1050
+
1051
+ def __exit__(
1052
+ self,
1053
+ exc_type: type[BaseException] | None,
1054
+ exc_value: BaseException | None,
1055
+ traceback: TracebackType | None,
1056
+ ) -> bool:
1057
+ """Release resources when leaving a context manager block."""
1058
+
1059
+ del exc_value, traceback
1060
+ self._close(suppress_errors=exc_type is not None)
1061
+ return False
1062
+
1063
+ def __del__(self) -> None:
1064
+ """Best-effort cleanup for engines not explicitly closed by callers."""
1065
+
1066
+ try:
1067
+ self._close(suppress_errors=True)
1068
+ except Exception:
1069
+ pass
1070
+
1071
+ def _ensure_open(self) -> None:
1072
+ """Raise when inference is attempted after backend disposal."""
1073
+
1074
+ if getattr(self, "_closed", False):
1075
+ raise RuntimeError("MBLT_Engine is closed.")
1076
+
1077
+ def _close(self, *, suppress_errors: bool) -> None:
1078
+ """Dispose acquired backends once, optionally suppressing cleanup failures."""
1079
+
1080
+ if getattr(self, "_closed", False):
1081
+ return
1082
+ self._closed = True
1083
+ first_error: Exception | None = None
1084
+ for backend in (
1085
+ getattr(self, "_mxq_model", None),
1086
+ getattr(self, "_onnx_model", None),
1087
+ ):
1088
+ if backend is None:
1089
+ continue
1090
+ try:
1091
+ backend.dispose()
1092
+ except Exception as exc:
1093
+ if first_error is None:
1094
+ first_error = exc
1095
+ self._onnx_session = None
1096
+ if first_error is not None and not suppress_errors:
1097
+ raise first_error
1098
+
1099
+ def model_name_aliasing(self, model_name: str) -> str:
1100
+ """Finds the YAML config filename that matches the given model name.
1101
+
1102
+ Matching is case-insensitive and first preserves separator boundaries
1103
+ so names such as ``regnet_x_16gf`` do not collide with
1104
+ ``regnet_x_1_6gf``. A separator-stripped fallback is used only when it
1105
+ resolves to a single unique configuration, so inputs like ``resnet50``,
1106
+ ``ResNet50``, ``Resnet_50``, and ``resnet-50`` all resolve to
1107
+ ``ResNet50.yaml``.
1108
+
1109
+ Args:
1110
+ model_name: The model identifier provided by the caller.
1111
+
1112
+ Returns:
1113
+ The exact YAML filename (basename only) stored in
1114
+ ``MODEL_CONFIG_DIR`` that corresponds to ``model_name``.
1115
+
1116
+ Raises:
1117
+ ValueError: If no YAML file matches, or if the name is ambiguous
1118
+ (i.e., multiple files match after normalization).
1119
+ """
1120
+
1121
+ return _model_name_aliasing(model_name)