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.
- mblt_vision/__init__.py +86 -0
- mblt_vision/_api.py +53 -0
- mblt_vision/_compat.py +227 -0
- mblt_vision/_model_paths.py +137 -0
- mblt_vision/_tasks.py +30 -0
- mblt_vision/benchmark/__init__.py +1 -0
- mblt_vision/benchmark/argparse_utils.py +106 -0
- mblt_vision/benchmark/chart_utils.py +146 -0
- mblt_vision/benchmark/io_utils.py +64 -0
- mblt_vision/benchmark/summary_utils.py +770 -0
- mblt_vision/cli/__init__.py +5 -0
- mblt_vision/cli/__main__.py +5 -0
- mblt_vision/cli/_vision.py +337 -0
- mblt_vision/cli/compile.py +117 -0
- mblt_vision/cli/main.py +35 -0
- mblt_vision/cli/predict.py +64 -0
- mblt_vision/cli/val.py +562 -0
- mblt_vision/compile/__init__.py +21 -0
- mblt_vision/compile/vision.py +1120 -0
- mblt_vision/datasets/__init__.py +15 -0
- mblt_vision/datasets/ade20k.yaml +164 -0
- mblt_vision/datasets/cityscapes.yaml +54 -0
- mblt_vision/datasets/coco.yaml +178 -0
- mblt_vision/datasets/dotav1.yaml +28 -0
- mblt_vision/datasets/imagenet.yaml +1019 -0
- mblt_vision/datasets/imagenet_synsets.txt +1000 -0
- mblt_vision/datasets/nyu-depth.yaml +7 -0
- mblt_vision/datasets/registry.py +158 -0
- mblt_vision/datasets/widerface.yaml +9 -0
- mblt_vision/depth_estimation/__init__.py +19 -0
- mblt_vision/face_detection/__init__.py +43 -0
- mblt_vision/image_classification/__init__.py +311 -0
- mblt_vision/instance_segmentation/__init__.py +65 -0
- mblt_vision/models/AlexNet.yaml +23 -0
- mblt_vision/models/CAFormer_B36.yaml +22 -0
- mblt_vision/models/CAFormer_M36.yaml +22 -0
- mblt_vision/models/CAFormer_S18.yaml +22 -0
- mblt_vision/models/CAFormer_S36.yaml +22 -0
- mblt_vision/models/CoAtNet_0_RW_224.yaml +22 -0
- mblt_vision/models/CoAtNet_1_RW_224.yaml +22 -0
- mblt_vision/models/CoAtNet_2_RW_224.yaml +22 -0
- mblt_vision/models/ConvFormer_B36.yaml +22 -0
- mblt_vision/models/ConvFormer_M36.yaml +22 -0
- mblt_vision/models/ConvFormer_S18.yaml +22 -0
- mblt_vision/models/ConvFormer_S36.yaml +22 -0
- mblt_vision/models/ConvNext_Base.yaml +23 -0
- mblt_vision/models/ConvNext_Large.yaml +23 -0
- mblt_vision/models/ConvNext_Small.yaml +23 -0
- mblt_vision/models/ConvNext_Tiny.yaml +23 -0
- mblt_vision/models/DeiT3_Base_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT3_Base_Patch16_384.yaml +22 -0
- mblt_vision/models/DeiT3_Large_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT3_Large_Patch16_384.yaml +22 -0
- mblt_vision/models/DeiT3_Medium_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT3_Small_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT3_Small_Patch16_384.yaml +22 -0
- mblt_vision/models/DeiT_Base_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT_Base_Patch16_384.yaml +22 -0
- mblt_vision/models/DeiT_Small_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT_Tiny_Patch16_224.yaml +22 -0
- mblt_vision/models/DenseNet121.yaml +23 -0
- mblt_vision/models/DenseNet161.yaml +23 -0
- mblt_vision/models/DenseNet169.yaml +23 -0
- mblt_vision/models/DenseNet201.yaml +23 -0
- mblt_vision/models/EfficientFormer_L1.yaml +22 -0
- mblt_vision/models/EfficientFormer_L3.yaml +22 -0
- mblt_vision/models/EfficientFormer_L7.yaml +22 -0
- mblt_vision/models/EfficientNet_B0.yaml +23 -0
- mblt_vision/models/EfficientNet_B1.yaml +32 -0
- mblt_vision/models/EfficientNet_B2.yaml +23 -0
- mblt_vision/models/EfficientNet_B3.yaml +23 -0
- mblt_vision/models/EfficientNet_B4.yaml +23 -0
- mblt_vision/models/EfficientNet_B5.yaml +23 -0
- mblt_vision/models/EfficientNet_B6.yaml +23 -0
- mblt_vision/models/EfficientNet_B7.yaml +23 -0
- mblt_vision/models/EfficientNet_V2_L.yaml +23 -0
- mblt_vision/models/EfficientNet_V2_M.yaml +23 -0
- mblt_vision/models/EfficientNet_V2_S.yaml +23 -0
- mblt_vision/models/FlexiVit_Base.yaml +22 -0
- mblt_vision/models/FlexiVit_Large.yaml +22 -0
- mblt_vision/models/FlexiVit_Small.yaml +22 -0
- mblt_vision/models/GELANc-seg.yaml +29 -0
- mblt_vision/models/GELANc.yaml +28 -0
- mblt_vision/models/GELANe.yaml +28 -0
- mblt_vision/models/GELANm.yaml +28 -0
- mblt_vision/models/GELANs.yaml +28 -0
- mblt_vision/models/GoogLeNet.yaml +23 -0
- mblt_vision/models/Inception_V3.yaml +23 -0
- mblt_vision/models/LeViT_Conv_128.yaml +22 -0
- mblt_vision/models/LeViT_Conv_128S.yaml +22 -0
- mblt_vision/models/LeViT_Conv_192.yaml +22 -0
- mblt_vision/models/LeViT_Conv_256.yaml +22 -0
- mblt_vision/models/LeViT_Conv_384.yaml +22 -0
- mblt_vision/models/MNASNet0_5.yaml +23 -0
- mblt_vision/models/MNASNet0_75.yaml +23 -0
- mblt_vision/models/MNASNet1_0.yaml +23 -0
- mblt_vision/models/MNASNet1_3.yaml +23 -0
- mblt_vision/models/MobileNet_V2.yaml +32 -0
- mblt_vision/models/MobileNet_V3_Large.yaml +32 -0
- mblt_vision/models/MobileNet_V3_Small.yaml +23 -0
- mblt_vision/models/RegNet_X_16GF.yaml +32 -0
- mblt_vision/models/RegNet_X_1_6GF.yaml +32 -0
- mblt_vision/models/RegNet_X_32GF.yaml +32 -0
- mblt_vision/models/RegNet_X_3_2GF.yaml +32 -0
- mblt_vision/models/RegNet_X_400MF.yaml +32 -0
- mblt_vision/models/RegNet_X_800MF.yaml +32 -0
- mblt_vision/models/RegNet_X_8GF.yaml +32 -0
- mblt_vision/models/RegNet_Y_16GF.yaml +76 -0
- mblt_vision/models/RegNet_Y_1_6GF.yaml +32 -0
- mblt_vision/models/RegNet_Y_32GF.yaml +76 -0
- mblt_vision/models/RegNet_Y_3_2GF.yaml +32 -0
- mblt_vision/models/RegNet_Y_400MF.yaml +32 -0
- mblt_vision/models/RegNet_Y_800MF.yaml +32 -0
- mblt_vision/models/RegNet_Y_8GF.yaml +32 -0
- mblt_vision/models/RepViT_M0_9.yaml +22 -0
- mblt_vision/models/RepViT_M1.yaml +22 -0
- mblt_vision/models/RepViT_M1_0.yaml +22 -0
- mblt_vision/models/RepViT_M1_1.yaml +22 -0
- mblt_vision/models/RepViT_M1_5.yaml +22 -0
- mblt_vision/models/RepViT_M2.yaml +22 -0
- mblt_vision/models/RepViT_M2_3.yaml +22 -0
- mblt_vision/models/RepViT_M3.yaml +22 -0
- mblt_vision/models/ResNeXt101_32X8D.yaml +32 -0
- mblt_vision/models/ResNeXt101_64X4D.yaml +23 -0
- mblt_vision/models/ResNeXt50_32X4D.yaml +32 -0
- mblt_vision/models/ResNet101.yaml +32 -0
- mblt_vision/models/ResNet152.yaml +32 -0
- mblt_vision/models/ResNet18.yaml +23 -0
- mblt_vision/models/ResNet34.yaml +23 -0
- mblt_vision/models/ResNet50.yaml +32 -0
- mblt_vision/models/ShuffleNet_V2_X0_5.yaml +23 -0
- mblt_vision/models/ShuffleNet_V2_X1_0.yaml +23 -0
- mblt_vision/models/ShuffleNet_V2_X1_5.yaml +23 -0
- mblt_vision/models/ShuffleNet_V2_X2_0.yaml +23 -0
- mblt_vision/models/SqueezeNet1_0.yaml +23 -0
- mblt_vision/models/SqueezeNet1_1.yaml +23 -0
- mblt_vision/models/Swin_B.yaml +23 -0
- mblt_vision/models/Swin_S.yaml +23 -0
- mblt_vision/models/Swin_T.yaml +23 -0
- mblt_vision/models/VGG11.yaml +23 -0
- mblt_vision/models/VGG11_BN.yaml +23 -0
- mblt_vision/models/VGG13.yaml +23 -0
- mblt_vision/models/VGG13_BN.yaml +23 -0
- mblt_vision/models/VGG16.yaml +23 -0
- mblt_vision/models/VGG16_BN.yaml +23 -0
- mblt_vision/models/VGG19.yaml +23 -0
- mblt_vision/models/VGG19_BN.yaml +23 -0
- mblt_vision/models/ViT_B_16.yaml +67 -0
- mblt_vision/models/ViT_B_32.yaml +23 -0
- mblt_vision/models/ViT_Base_Patch16_224.yaml +22 -0
- mblt_vision/models/ViT_Base_Patch16_384.yaml +22 -0
- mblt_vision/models/ViT_Base_Patch32_224.yaml +22 -0
- mblt_vision/models/ViT_Base_Patch32_384.yaml +22 -0
- mblt_vision/models/ViT_Base_Patch8_224.yaml +22 -0
- mblt_vision/models/ViT_L_16.yaml +67 -0
- mblt_vision/models/ViT_L_32.yaml +23 -0
- mblt_vision/models/ViT_Large_Patch16_224.yaml +22 -0
- mblt_vision/models/ViT_Large_Patch16_384.yaml +22 -0
- mblt_vision/models/ViT_Large_Patch32_384.yaml +22 -0
- mblt_vision/models/ViT_Small_Patch16_224.yaml +22 -0
- mblt_vision/models/ViT_Small_Patch16_384.yaml +22 -0
- mblt_vision/models/ViT_Small_Patch32_224.yaml +22 -0
- mblt_vision/models/ViT_Small_Patch32_384.yaml +22 -0
- mblt_vision/models/ViT_Tiny_Patch16_224.yaml +22 -0
- mblt_vision/models/ViT_Tiny_Patch16_384.yaml +22 -0
- mblt_vision/models/VisFormer_Small.yaml +22 -0
- mblt_vision/models/VisFormer_Tiny.yaml +22 -0
- mblt_vision/models/Wide_ResNet101_2.yaml +32 -0
- mblt_vision/models/Wide_ResNet50_2.yaml +32 -0
- mblt_vision/models/YOLO11l-cls.yaml +23 -0
- mblt_vision/models/YOLO11l-face.yaml +27 -0
- mblt_vision/models/YOLO11l-obb.yaml +28 -0
- mblt_vision/models/YOLO11l-pose.yaml +28 -0
- mblt_vision/models/YOLO11l-seg.yaml +28 -0
- mblt_vision/models/YOLO11l.yaml +27 -0
- mblt_vision/models/YOLO11m-cls.yaml +23 -0
- mblt_vision/models/YOLO11m-face.yaml +27 -0
- mblt_vision/models/YOLO11m-obb.yaml +28 -0
- mblt_vision/models/YOLO11m-pose.yaml +28 -0
- mblt_vision/models/YOLO11m-seg.yaml +28 -0
- mblt_vision/models/YOLO11m.yaml +27 -0
- mblt_vision/models/YOLO11n-cls.yaml +23 -0
- mblt_vision/models/YOLO11n-face.yaml +27 -0
- mblt_vision/models/YOLO11n-obb.yaml +28 -0
- mblt_vision/models/YOLO11n-pose.yaml +28 -0
- mblt_vision/models/YOLO11n-seg.yaml +28 -0
- mblt_vision/models/YOLO11n.yaml +27 -0
- mblt_vision/models/YOLO11s-cls.yaml +23 -0
- mblt_vision/models/YOLO11s-face.yaml +27 -0
- mblt_vision/models/YOLO11s-obb.yaml +28 -0
- mblt_vision/models/YOLO11s-pose.yaml +28 -0
- mblt_vision/models/YOLO11s-seg.yaml +28 -0
- mblt_vision/models/YOLO11s.yaml +27 -0
- mblt_vision/models/YOLO11x-cls.yaml +23 -0
- mblt_vision/models/YOLO11x-obb.yaml +28 -0
- mblt_vision/models/YOLO11x-pose.yaml +28 -0
- mblt_vision/models/YOLO11x-seg.yaml +28 -0
- mblt_vision/models/YOLO11x.yaml +27 -0
- mblt_vision/models/YOLO12l-face.yaml +27 -0
- mblt_vision/models/YOLO12l-seg.yaml +28 -0
- mblt_vision/models/YOLO12l.yaml +27 -0
- mblt_vision/models/YOLO12m-face.yaml +27 -0
- mblt_vision/models/YOLO12m-seg.yaml +28 -0
- mblt_vision/models/YOLO12m.yaml +27 -0
- mblt_vision/models/YOLO12n-face.yaml +27 -0
- mblt_vision/models/YOLO12n-seg.yaml +28 -0
- mblt_vision/models/YOLO12n.yaml +27 -0
- mblt_vision/models/YOLO12s-face.yaml +27 -0
- mblt_vision/models/YOLO12s-seg.yaml +28 -0
- mblt_vision/models/YOLO12s.yaml +27 -0
- mblt_vision/models/YOLO12x-seg.yaml +28 -0
- mblt_vision/models/YOLO12x.yaml +27 -0
- mblt_vision/models/YOLO26l-cls.yaml +23 -0
- mblt_vision/models/YOLO26l-depth.yaml +17 -0
- mblt_vision/models/YOLO26l-distill.yaml +27 -0
- mblt_vision/models/YOLO26l-obb.yaml +28 -0
- mblt_vision/models/YOLO26l-pose.yaml +28 -0
- mblt_vision/models/YOLO26l-seg.yaml +28 -0
- mblt_vision/models/YOLO26l-sem-ade20k.yaml +17 -0
- mblt_vision/models/YOLO26l-sem.yaml +17 -0
- mblt_vision/models/YOLO26l.yaml +27 -0
- mblt_vision/models/YOLO26m-cls.yaml +23 -0
- mblt_vision/models/YOLO26m-depth.yaml +17 -0
- mblt_vision/models/YOLO26m-distill.yaml +27 -0
- mblt_vision/models/YOLO26m-obb.yaml +28 -0
- mblt_vision/models/YOLO26m-pose.yaml +28 -0
- mblt_vision/models/YOLO26m-seg.yaml +28 -0
- mblt_vision/models/YOLO26m-sem-ade20k.yaml +17 -0
- mblt_vision/models/YOLO26m-sem.yaml +17 -0
- mblt_vision/models/YOLO26m.yaml +27 -0
- mblt_vision/models/YOLO26n-cls.yaml +23 -0
- mblt_vision/models/YOLO26n-depth.yaml +17 -0
- mblt_vision/models/YOLO26n-distill.yaml +27 -0
- mblt_vision/models/YOLO26n-obb.yaml +28 -0
- mblt_vision/models/YOLO26n-pose.yaml +28 -0
- mblt_vision/models/YOLO26n-seg.yaml +28 -0
- mblt_vision/models/YOLO26n-sem-ade20k.yaml +17 -0
- mblt_vision/models/YOLO26n-sem.yaml +17 -0
- mblt_vision/models/YOLO26n.yaml +27 -0
- mblt_vision/models/YOLO26s-cls.yaml +23 -0
- mblt_vision/models/YOLO26s-depth.yaml +17 -0
- mblt_vision/models/YOLO26s-distill.yaml +27 -0
- mblt_vision/models/YOLO26s-obb.yaml +28 -0
- mblt_vision/models/YOLO26s-pose.yaml +28 -0
- mblt_vision/models/YOLO26s-seg.yaml +28 -0
- mblt_vision/models/YOLO26s-sem-ade20k.yaml +17 -0
- mblt_vision/models/YOLO26s-sem.yaml +17 -0
- mblt_vision/models/YOLO26s.yaml +27 -0
- mblt_vision/models/YOLO26x-cls.yaml +23 -0
- mblt_vision/models/YOLO26x-depth.yaml +17 -0
- mblt_vision/models/YOLO26x-distill.yaml +27 -0
- mblt_vision/models/YOLO26x-obb.yaml +28 -0
- mblt_vision/models/YOLO26x-pose.yaml +28 -0
- mblt_vision/models/YOLO26x-seg.yaml +28 -0
- mblt_vision/models/YOLO26x-sem-ade20k.yaml +17 -0
- mblt_vision/models/YOLO26x-sem.yaml +17 -0
- mblt_vision/models/YOLO26x.yaml +27 -0
- mblt_vision/models/YOLOv10b.yaml +28 -0
- mblt_vision/models/YOLOv10l-face.yaml +28 -0
- mblt_vision/models/YOLOv10l.yaml +28 -0
- mblt_vision/models/YOLOv10m-face.yaml +28 -0
- mblt_vision/models/YOLOv10m.yaml +28 -0
- mblt_vision/models/YOLOv10n-face.yaml +28 -0
- mblt_vision/models/YOLOv10n.yaml +28 -0
- mblt_vision/models/YOLOv10s-face.yaml +28 -0
- mblt_vision/models/YOLOv10s.yaml +28 -0
- mblt_vision/models/YOLOv10x.yaml +28 -0
- mblt_vision/models/YOLOv3-spp.yaml +44 -0
- mblt_vision/models/YOLOv3-sppu.yaml +27 -0
- mblt_vision/models/YOLOv3-tiny.yaml +38 -0
- mblt_vision/models/YOLOv3-tinyu.yaml +27 -0
- mblt_vision/models/YOLOv3.yaml +44 -0
- mblt_vision/models/YOLOv3u.yaml +27 -0
- mblt_vision/models/YOLOv5l-cls.yaml +22 -0
- mblt_vision/models/YOLOv5l-seg.yaml +45 -0
- mblt_vision/models/YOLOv5l.yaml +44 -0
- mblt_vision/models/YOLOv5l6.yaml +50 -0
- mblt_vision/models/YOLOv5l6u.yaml +27 -0
- mblt_vision/models/YOLOv5lu.yaml +27 -0
- mblt_vision/models/YOLOv5m-cls.yaml +22 -0
- mblt_vision/models/YOLOv5m-seg.yaml +45 -0
- mblt_vision/models/YOLOv5m.yaml +45 -0
- mblt_vision/models/YOLOv5m6.yaml +50 -0
- mblt_vision/models/YOLOv5m6u.yaml +27 -0
- mblt_vision/models/YOLOv5mu.yaml +27 -0
- mblt_vision/models/YOLOv5n-cls.yaml +22 -0
- mblt_vision/models/YOLOv5n-seg.yaml +45 -0
- mblt_vision/models/YOLOv5n.yaml +44 -0
- mblt_vision/models/YOLOv5n6.yaml +50 -0
- mblt_vision/models/YOLOv5n6u.yaml +27 -0
- mblt_vision/models/YOLOv5nu.yaml +27 -0
- mblt_vision/models/YOLOv5s-cls.yaml +22 -0
- mblt_vision/models/YOLOv5s-seg.yaml +45 -0
- mblt_vision/models/YOLOv5s.yaml +44 -0
- mblt_vision/models/YOLOv5s6.yaml +50 -0
- mblt_vision/models/YOLOv5s6u.yaml +27 -0
- mblt_vision/models/YOLOv5su.yaml +27 -0
- mblt_vision/models/YOLOv5x-cls.yaml +22 -0
- mblt_vision/models/YOLOv5x-seg.yaml +45 -0
- mblt_vision/models/YOLOv5x.yaml +44 -0
- mblt_vision/models/YOLOv5x6.yaml +50 -0
- mblt_vision/models/YOLOv5x6u.yaml +27 -0
- mblt_vision/models/YOLOv5xu.yaml +27 -0
- mblt_vision/models/YOLOv6m-face.yaml +27 -0
- mblt_vision/models/YOLOv6n-face.yaml +27 -0
- mblt_vision/models/YOLOv7.yaml +44 -0
- mblt_vision/models/YOLOv7d6.yaml +50 -0
- mblt_vision/models/YOLOv7e6.yaml +50 -0
- mblt_vision/models/YOLOv7e6e.yaml +50 -0
- mblt_vision/models/YOLOv7w6.yaml +50 -0
- mblt_vision/models/YOLOv7x.yaml +44 -0
- mblt_vision/models/YOLOv8l-cls.yaml +23 -0
- mblt_vision/models/YOLOv8l-face.yaml +27 -0
- mblt_vision/models/YOLOv8l-obb.yaml +28 -0
- mblt_vision/models/YOLOv8l-pose.yaml +28 -0
- mblt_vision/models/YOLOv8l-seg.yaml +28 -0
- mblt_vision/models/YOLOv8l.yaml +27 -0
- mblt_vision/models/YOLOv8m-cls.yaml +23 -0
- mblt_vision/models/YOLOv8m-face.yaml +27 -0
- mblt_vision/models/YOLOv8m-obb.yaml +28 -0
- mblt_vision/models/YOLOv8m-pose.yaml +28 -0
- mblt_vision/models/YOLOv8m-seg.yaml +28 -0
- mblt_vision/models/YOLOv8m.yaml +27 -0
- mblt_vision/models/YOLOv8n-cls.yaml +23 -0
- mblt_vision/models/YOLOv8n-face.yaml +27 -0
- mblt_vision/models/YOLOv8n-obb.yaml +28 -0
- mblt_vision/models/YOLOv8n-pose.yaml +28 -0
- mblt_vision/models/YOLOv8n-seg.yaml +28 -0
- mblt_vision/models/YOLOv8n.yaml +27 -0
- mblt_vision/models/YOLOv8s-cls.yaml +23 -0
- mblt_vision/models/YOLOv8s-obb.yaml +28 -0
- mblt_vision/models/YOLOv8s-pose.yaml +28 -0
- mblt_vision/models/YOLOv8s-seg.yaml +28 -0
- mblt_vision/models/YOLOv8s.yaml +27 -0
- mblt_vision/models/YOLOv8x-cls.yaml +23 -0
- mblt_vision/models/YOLOv8x-obb.yaml +28 -0
- mblt_vision/models/YOLOv8x-pose-p6.yaml +28 -0
- mblt_vision/models/YOLOv8x-pose.yaml +28 -0
- mblt_vision/models/YOLOv8x-seg.yaml +28 -0
- mblt_vision/models/YOLOv8x.yaml +27 -0
- mblt_vision/models/YOLOv9c-seg.yaml +28 -0
- mblt_vision/models/YOLOv9c.yaml +27 -0
- mblt_vision/models/YOLOv9e-seg.yaml +28 -0
- mblt_vision/models/YOLOv9e.yaml +27 -0
- mblt_vision/models/YOLOv9m.yaml +27 -0
- mblt_vision/models/YOLOv9s.yaml +27 -0
- mblt_vision/models/YOLOv9t.yaml +27 -0
- mblt_vision/obb/__init__.py +39 -0
- mblt_vision/object_detection/__init__.py +153 -0
- mblt_vision/pose_estimation/__init__.py +41 -0
- mblt_vision/py.typed +1 -0
- mblt_vision/semantic_segmentation/__init__.py +29 -0
- mblt_vision/utils/__init__.py +0 -0
- mblt_vision/utils/datasets/__init__.py +85 -0
- mblt_vision/utils/datasets/ade20k.py +41 -0
- mblt_vision/utils/datasets/cityscapes.py +66 -0
- mblt_vision/utils/datasets/coco.py +243 -0
- mblt_vision/utils/datasets/dataloader.py +1016 -0
- mblt_vision/utils/datasets/dotav1.py +59 -0
- mblt_vision/utils/datasets/imagenet.py +29 -0
- mblt_vision/utils/datasets/organizer.py +2145 -0
- mblt_vision/utils/datasets/readiness.py +1063 -0
- mblt_vision/utils/evaluation/__init__.py +51 -0
- mblt_vision/utils/evaluation/_result.py +22 -0
- mblt_vision/utils/evaluation/eval_ade20k.py +302 -0
- mblt_vision/utils/evaluation/eval_cityscapes.py +32 -0
- mblt_vision/utils/evaluation/eval_coco.py +465 -0
- mblt_vision/utils/evaluation/eval_dota.py +878 -0
- mblt_vision/utils/evaluation/eval_imagenet.py +151 -0
- mblt_vision/utils/evaluation/eval_nyu_depth.py +189 -0
- mblt_vision/utils/evaluation/eval_widerface.py +440 -0
- mblt_vision/utils/letterbox.py +118 -0
- mblt_vision/utils/postprocess/__init__.py +9 -0
- mblt_vision/utils/postprocess/_letterbox.py +102 -0
- mblt_vision/utils/postprocess/base.py +743 -0
- mblt_vision/utils/postprocess/build_post.py +120 -0
- mblt_vision/utils/postprocess/cls_post.py +117 -0
- mblt_vision/utils/postprocess/common.py +1571 -0
- mblt_vision/utils/postprocess/depth_post.py +106 -0
- mblt_vision/utils/postprocess/semantic_seg_post.py +192 -0
- mblt_vision/utils/postprocess/yolo_anchor_post.py +469 -0
- mblt_vision/utils/postprocess/yolo_anchorless_post.py +952 -0
- mblt_vision/utils/postprocess/yolo_dflfree_post.py +983 -0
- mblt_vision/utils/postprocess/yolo_nmsfree_post.py +176 -0
- mblt_vision/utils/preprocess/__init__.py +27 -0
- mblt_vision/utils/preprocess/_validation.py +66 -0
- mblt_vision/utils/preprocess/base.py +157 -0
- mblt_vision/utils/preprocess/build_pre.py +48 -0
- mblt_vision/utils/preprocess/center_crop.py +75 -0
- mblt_vision/utils/preprocess/letterbox.py +123 -0
- mblt_vision/utils/preprocess/normalize.py +94 -0
- mblt_vision/utils/preprocess/order.py +74 -0
- mblt_vision/utils/preprocess/reader.py +94 -0
- mblt_vision/utils/preprocess/resize.py +202 -0
- mblt_vision/utils/preprocess/yolo_pre.py +7 -0
- mblt_vision/utils/results.py +725 -0
- mblt_vision/utils/types.py +15 -0
- mblt_vision/wrapper.py +1121 -0
- mblt_vision_python-0.0.0.dist-info/METADATA +152 -0
- mblt_vision_python-0.0.0.dist-info/RECORD +404 -0
- mblt_vision_python-0.0.0.dist-info/WHEEL +5 -0
- mblt_vision_python-0.0.0.dist-info/entry_points.txt +2 -0
- mblt_vision_python-0.0.0.dist-info/licenses/LICENSE +28 -0
- mblt_vision_python-0.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,770 @@
|
|
|
1
|
+
"""Markdown summary helpers for benchmark outputs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import re
|
|
7
|
+
import subprocess
|
|
8
|
+
from collections.abc import Mapping, Sequence
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
HOST_PC_INFO_FILENAME = "host_pc_info.json"
|
|
14
|
+
|
|
15
|
+
_HOST_INFO_SECTION_ORDER = ("CPU", "Motherboard", "DRAM", "NPU")
|
|
16
|
+
|
|
17
|
+
_HOST_INFO_SECTION_ALIASES = {
|
|
18
|
+
"cpu": "CPU",
|
|
19
|
+
"processor": "CPU",
|
|
20
|
+
"motherboard": "Motherboard",
|
|
21
|
+
"mainboard": "Motherboard",
|
|
22
|
+
"baseboard": "Motherboard",
|
|
23
|
+
"board": "Motherboard",
|
|
24
|
+
"dram": "DRAM",
|
|
25
|
+
"memory": "DRAM",
|
|
26
|
+
"ram": "DRAM",
|
|
27
|
+
"dimm": "DRAM",
|
|
28
|
+
"npu": "NPU",
|
|
29
|
+
"npus": "NPU",
|
|
30
|
+
"neural": "NPU",
|
|
31
|
+
"accelerator": "NPU",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
_NPU_ARRAY_KEY_RE = re.compile(r"(?:^|\.)npus\[(\d+)\]\.(.+)$")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
_PLOT_TITLES_BY_NAME = {
|
|
38
|
+
"rtf.png": "Real-Time Factor",
|
|
39
|
+
"inverse_rtf.png": "Inverse Real-Time Factor",
|
|
40
|
+
"sec_per_j.png": "Seconds Per Joule",
|
|
41
|
+
"j_per_sec.png": "Joules Per Audio Second",
|
|
42
|
+
"wer.png": "Word Error Rate",
|
|
43
|
+
"cer.png": "Character Error Rate",
|
|
44
|
+
"p95_latency_s.png": "P95 Latency",
|
|
45
|
+
"throughput_samples_per_s.png": "Throughput",
|
|
46
|
+
"decode_tokens_per_s.png": "Decode Tokens Per Second",
|
|
47
|
+
"prefill_tps.png": "Prefill Tokens Per Second",
|
|
48
|
+
"measure_prefill_tps.png": "Prefill Tokens Per Second",
|
|
49
|
+
"llm_prefill_tps.png": "Prefill Tokens Per Second",
|
|
50
|
+
"measure_llm_prefill_tps.png": "Prefill Tokens Per Second",
|
|
51
|
+
"prefill_tps_per_w.png": "Prefill TPS/W",
|
|
52
|
+
"measure_prefill_tps_per_w.png": "Prefill TPS/W",
|
|
53
|
+
"llm_prefill_tps_per_w.png": "Prefill TPS/W",
|
|
54
|
+
"measure_llm_prefill_tps_per_w.png": "Prefill TPS/W",
|
|
55
|
+
"decode_tps.png": "Decode Tokens Per Second",
|
|
56
|
+
"measure_decode_tps.png": "Decode Tokens Per Second",
|
|
57
|
+
"llm_decode_tps.png": "Decode Tokens Per Second",
|
|
58
|
+
"measure_llm_decode_tps.png": "Decode Tokens Per Second",
|
|
59
|
+
"decode_tps_per_w.png": "Decode TPS/W",
|
|
60
|
+
"measure_decode_tps_per_w.png": "Decode TPS/W",
|
|
61
|
+
"llm_decode_tps_per_w.png": "Decode TPS/W",
|
|
62
|
+
"measure_llm_decode_tps_per_w.png": "Decode TPS/W",
|
|
63
|
+
"avg_power_w.png": "Power",
|
|
64
|
+
"measure_avg_power_w.png": "Power",
|
|
65
|
+
"avg_temperature_c.png": "Temperature",
|
|
66
|
+
"measure_avg_temperature_c.png": "Temperature",
|
|
67
|
+
"avg_utilization_pct.png": "Utilization",
|
|
68
|
+
"measure_avg_utilization_pct.png": "Utilization",
|
|
69
|
+
"avg_memory_used_mb.png": "Memory Used Megabytes",
|
|
70
|
+
"measure_avg_memory_used_mb.png": "Memory Used Megabytes",
|
|
71
|
+
"total_energy_j.png": "Total Energy",
|
|
72
|
+
"measure_total_energy_j.png": "Total Energy",
|
|
73
|
+
"vision_fps.png": "Vision FPS",
|
|
74
|
+
"vision_encode_ms.png": "Vision Encode ms",
|
|
75
|
+
"vision_img_per_j.png": "Vision Images Per Joule",
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
_PLOT_NAME_ORDER = {name: idx for idx, name in enumerate(_PLOT_TITLES_BY_NAME)}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def collect_host_pc_info(
|
|
82
|
+
results_dir: Path | str, *, filename: str = HOST_PC_INFO_FILENAME
|
|
83
|
+
) -> Path:
|
|
84
|
+
"""Run ``mblt-tracker collect`` and save its JSON output.
|
|
85
|
+
|
|
86
|
+
The benchmark should not fail just because host information collection is unavailable. Failures are therefore
|
|
87
|
+
converted into a JSON payload that can still be rendered in the summary.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
results_dir: Benchmark output directory.
|
|
91
|
+
filename: JSON filename to write under ``results_dir``.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
Path to the written JSON file.
|
|
95
|
+
"""
|
|
96
|
+
out_dir = Path(results_dir)
|
|
97
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
98
|
+
output_path = out_dir / filename
|
|
99
|
+
payload: Any
|
|
100
|
+
try:
|
|
101
|
+
proc = subprocess.run(
|
|
102
|
+
["mblt-tracker", "collect"],
|
|
103
|
+
check=False,
|
|
104
|
+
capture_output=True,
|
|
105
|
+
encoding="utf-8",
|
|
106
|
+
timeout=30,
|
|
107
|
+
)
|
|
108
|
+
if proc.returncode == 0:
|
|
109
|
+
try:
|
|
110
|
+
payload = json.loads(proc.stdout)
|
|
111
|
+
except json.JSONDecodeError:
|
|
112
|
+
payload = {
|
|
113
|
+
"status": "error",
|
|
114
|
+
"message": "mblt-tracker collect did not return valid JSON.",
|
|
115
|
+
"stdout": proc.stdout,
|
|
116
|
+
"stderr": proc.stderr,
|
|
117
|
+
"returncode": proc.returncode,
|
|
118
|
+
}
|
|
119
|
+
else:
|
|
120
|
+
payload = {
|
|
121
|
+
"status": "error",
|
|
122
|
+
"message": "mblt-tracker collect failed.",
|
|
123
|
+
"stdout": proc.stdout,
|
|
124
|
+
"stderr": proc.stderr,
|
|
125
|
+
"returncode": proc.returncode,
|
|
126
|
+
}
|
|
127
|
+
except FileNotFoundError:
|
|
128
|
+
payload = {"status": "error", "message": "mblt-tracker CLI was not found."}
|
|
129
|
+
except subprocess.TimeoutExpired as e:
|
|
130
|
+
payload = {
|
|
131
|
+
"status": "error",
|
|
132
|
+
"message": "mblt-tracker collect timed out.",
|
|
133
|
+
"stdout": e.stdout,
|
|
134
|
+
"stderr": e.stderr,
|
|
135
|
+
"timeout_s": e.timeout,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
payload = _with_collection_metadata(payload)
|
|
139
|
+
with output_path.open("w", encoding="utf-8") as f:
|
|
140
|
+
json.dump(payload, f, ensure_ascii=False, indent=2)
|
|
141
|
+
print(f"Saved Host PC Info: {output_path.name}")
|
|
142
|
+
return output_path
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def write_summary_markdown(
|
|
146
|
+
path: Path | str,
|
|
147
|
+
*,
|
|
148
|
+
title: str,
|
|
149
|
+
host_info_path: Path | str | None,
|
|
150
|
+
table_markdown_path: Path | str | None,
|
|
151
|
+
plot_paths: Sequence[Path | str],
|
|
152
|
+
plot_tables: Mapping[str, str] | None = None,
|
|
153
|
+
host_info_paths: Mapping[str, Path | str] | None = None,
|
|
154
|
+
) -> None:
|
|
155
|
+
"""Write a benchmark summary Markdown file with host info, plots, and table.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
path: Summary Markdown destination.
|
|
159
|
+
title: Document title.
|
|
160
|
+
host_info_path: JSON file written by :func:`collect_host_pc_info`.
|
|
161
|
+
table_markdown_path: Existing Markdown table to include.
|
|
162
|
+
plot_paths: PNG files to embed in the summary.
|
|
163
|
+
plot_tables: Optional Markdown tables keyed by plot PNG filename. When provided, matching tables are rendered
|
|
164
|
+
directly below each plot and the bottom combined table is omitted.
|
|
165
|
+
host_info_paths: Optional source-labeled host info JSON files. When provided, host info is rendered per source.
|
|
166
|
+
"""
|
|
167
|
+
summary_path = Path(path)
|
|
168
|
+
summary_path.parent.mkdir(parents=True, exist_ok=True)
|
|
169
|
+
host_info_lines = (
|
|
170
|
+
_host_infos_markdown(
|
|
171
|
+
{label: Path(src_path) for label, src_path in host_info_paths.items()}
|
|
172
|
+
)
|
|
173
|
+
if host_info_paths
|
|
174
|
+
else _host_info_markdown(Path(host_info_path) if host_info_path else None)
|
|
175
|
+
)
|
|
176
|
+
lines = [f"# {title}\n\n"]
|
|
177
|
+
lines.extend(_device_energy_note_markdown())
|
|
178
|
+
lines.extend(
|
|
179
|
+
_plots_markdown(
|
|
180
|
+
summary_path.parent, [Path(p) for p in plot_paths], plot_tables=plot_tables
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
if not plot_tables:
|
|
184
|
+
lines.extend(
|
|
185
|
+
_table_markdown(Path(table_markdown_path) if table_markdown_path else None)
|
|
186
|
+
)
|
|
187
|
+
lines.extend(host_info_lines)
|
|
188
|
+
summary_path.write_text("".join(lines), encoding="utf-8")
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _device_energy_note_markdown() -> list[str]:
|
|
192
|
+
"""Return a reusable note describing trace-integrated energy limitations."""
|
|
193
|
+
|
|
194
|
+
return [
|
|
195
|
+
"## Device energy note\n\n",
|
|
196
|
+
"Energy and energy-efficiency metrics are computed from mblt-tracker power traces using "
|
|
197
|
+
"trapezoidal integration. At least two valid power samples are required, so measurements shorter "
|
|
198
|
+
"than the tracker sampling interval may leave energy fields empty.\n\n",
|
|
199
|
+
]
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def read_csv_rows(path: Path | str) -> list[dict[str, str]]:
|
|
203
|
+
"""Read CSV rows if the file exists.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
path: CSV path to read.
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
CSV rows as dictionaries, or an empty list when the file does not exist.
|
|
210
|
+
"""
|
|
211
|
+
csv_path = Path(path)
|
|
212
|
+
if not csv_path.is_file():
|
|
213
|
+
return []
|
|
214
|
+
import csv
|
|
215
|
+
|
|
216
|
+
with csv_path.open("r", encoding="utf-8", newline="") as f:
|
|
217
|
+
return list(csv.DictReader(f))
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def markdown_table(headers: Sequence[str], rows: Sequence[Sequence[Any]]) -> str:
|
|
221
|
+
"""Build a compact Markdown table with right-aligned metric columns.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
headers: Table headers.
|
|
225
|
+
rows: Table row values.
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
Markdown table text, or an empty string for empty rows.
|
|
229
|
+
"""
|
|
230
|
+
if not rows:
|
|
231
|
+
return ""
|
|
232
|
+
lines = [
|
|
233
|
+
"| " + " | ".join(_escape_markdown(header) for header in headers) + " |\n",
|
|
234
|
+
"| " + " | ".join(["---"] + ["---:" for _ in headers[1:]]) + " |\n",
|
|
235
|
+
]
|
|
236
|
+
for row in rows:
|
|
237
|
+
lines.append(
|
|
238
|
+
"| " + " | ".join(_format_summary_cell(value) for value in row) + " |\n"
|
|
239
|
+
)
|
|
240
|
+
return "".join(lines)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def scalar_plot_table(
|
|
244
|
+
rows: Sequence[Mapping[str, Any]], *, value_key: str, unit_header: str
|
|
245
|
+
) -> str:
|
|
246
|
+
"""Build a model/value table for one scalar plot.
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
rows: Rows containing a ``model`` key and the requested scalar key.
|
|
250
|
+
value_key: Key containing the scalar value.
|
|
251
|
+
unit_header: Header for the value column.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
Markdown table text.
|
|
255
|
+
"""
|
|
256
|
+
return markdown_table(
|
|
257
|
+
["Model", unit_header], [[row.get("model"), row.get(value_key)] for row in rows]
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def token_sweep_plot_table(
|
|
262
|
+
models: Sequence[str],
|
|
263
|
+
metrics_by_model: Mapping[str, Any],
|
|
264
|
+
*,
|
|
265
|
+
value_key: str,
|
|
266
|
+
) -> str:
|
|
267
|
+
"""Build a model/token table for one token-sweep plot.
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
models: Model names to include.
|
|
271
|
+
metrics_by_model: Mapping from model name to metric object with token dictionaries.
|
|
272
|
+
value_key: Attribute name containing a ``dict[int, float]`` token metric.
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
Markdown table text.
|
|
276
|
+
"""
|
|
277
|
+
token_set: set[int] = set()
|
|
278
|
+
for model in models:
|
|
279
|
+
token_set.update(getattr(metrics_by_model[model], value_key).keys())
|
|
280
|
+
tokens = sorted(token_set)
|
|
281
|
+
if not tokens:
|
|
282
|
+
return ""
|
|
283
|
+
table_rows = []
|
|
284
|
+
for model in models:
|
|
285
|
+
values = getattr(metrics_by_model[model], value_key)
|
|
286
|
+
table_rows.append([model, *(values.get(token) for token in tokens)])
|
|
287
|
+
return markdown_table(
|
|
288
|
+
["Model", *(f"{token} tokens" for token in tokens)], table_rows
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def write_token_combined_markdown(
|
|
293
|
+
path: Path | str,
|
|
294
|
+
tps_rows: Sequence[Mapping[str, Any]],
|
|
295
|
+
device_rows: Sequence[Mapping[str, Any]],
|
|
296
|
+
) -> None:
|
|
297
|
+
"""Write a wide-form token sweep Markdown table shared by transformer benchmarks.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
path: Markdown output path.
|
|
301
|
+
tps_rows: Long-form TPS rows from ``BenchmarkResult.iter_rows``.
|
|
302
|
+
device_rows: Per-model device metric rows.
|
|
303
|
+
"""
|
|
304
|
+
if not tps_rows:
|
|
305
|
+
return
|
|
306
|
+
models = sorted({str(r["model"]) for r in tps_rows})
|
|
307
|
+
prefill_tokens = sorted(
|
|
308
|
+
{
|
|
309
|
+
int(r["tokens"])
|
|
310
|
+
for r in tps_rows
|
|
311
|
+
if str(r.get("phase")) == "prefill" and _is_int_like(r.get("tokens"))
|
|
312
|
+
}
|
|
313
|
+
)
|
|
314
|
+
decode_tokens = sorted(
|
|
315
|
+
{
|
|
316
|
+
int(r["tokens"])
|
|
317
|
+
for r in tps_rows
|
|
318
|
+
if str(r.get("phase")) == "decode" and _is_int_like(r.get("tokens"))
|
|
319
|
+
}
|
|
320
|
+
)
|
|
321
|
+
tps_map: dict[tuple[str, str, int], float] = {}
|
|
322
|
+
time_map: dict[tuple[str, str, int], float] = {}
|
|
323
|
+
npu_pct_map: dict[tuple[str, str, int], float] = {}
|
|
324
|
+
for row in tps_rows:
|
|
325
|
+
model = str(row["model"])
|
|
326
|
+
phase = str(row["phase"])
|
|
327
|
+
token = int(row["tokens"])
|
|
328
|
+
tps_val = row.get("tps")
|
|
329
|
+
time_ms_val = row.get("time_ms")
|
|
330
|
+
npu_pct_val = row.get("avg_npu_token_latency_pct")
|
|
331
|
+
if isinstance(tps_val, (int, float)):
|
|
332
|
+
tps_map[(model, phase, token)] = float(tps_val)
|
|
333
|
+
if isinstance(time_ms_val, (int, float)):
|
|
334
|
+
time_map[(model, phase, token)] = float(time_ms_val)
|
|
335
|
+
if isinstance(npu_pct_val, (int, float)):
|
|
336
|
+
npu_pct_map[(model, phase, token)] = float(npu_pct_val)
|
|
337
|
+
|
|
338
|
+
device_map = {
|
|
339
|
+
str(r["model"]): r for r in device_rows if isinstance(r.get("model"), str)
|
|
340
|
+
}
|
|
341
|
+
device_cols = [
|
|
342
|
+
"avg_power_w",
|
|
343
|
+
"p99_power_w",
|
|
344
|
+
"avg_utilization_pct",
|
|
345
|
+
"p99_utilization_pct",
|
|
346
|
+
"avg_temperature_c",
|
|
347
|
+
"p99_temperature_c",
|
|
348
|
+
"avg_memory_used_mb",
|
|
349
|
+
"p99_memory_used_mb",
|
|
350
|
+
"total_memory_mb",
|
|
351
|
+
"avg_memory_used_pct",
|
|
352
|
+
"p99_memory_used_pct",
|
|
353
|
+
"total_energy_j",
|
|
354
|
+
"prefill_tps_last",
|
|
355
|
+
"decode_tps_last",
|
|
356
|
+
"prefill_tps_per_w_last",
|
|
357
|
+
"decode_tps_per_w_last",
|
|
358
|
+
"prefill_j_per_tok_last",
|
|
359
|
+
"decode_j_per_tok_last",
|
|
360
|
+
]
|
|
361
|
+
|
|
362
|
+
headers = ["model"]
|
|
363
|
+
headers.extend([f"prefill_tps_{t}" for t in prefill_tokens])
|
|
364
|
+
headers.extend([f"decode_tps_{t}" for t in decode_tokens])
|
|
365
|
+
headers.extend([f"prefill_latency_ms_{t}" for t in prefill_tokens])
|
|
366
|
+
headers.extend([f"decode_duration_ms_{t}" for t in decode_tokens])
|
|
367
|
+
headers.extend([f"prefill_npu_latency_pct_{t}" for t in prefill_tokens])
|
|
368
|
+
headers.extend([f"decode_npu_latency_pct_{t}" for t in decode_tokens])
|
|
369
|
+
headers.extend(device_cols)
|
|
370
|
+
|
|
371
|
+
rows: list[list[str]] = []
|
|
372
|
+
for model in models:
|
|
373
|
+
values: list[str] = [model]
|
|
374
|
+
for token in prefill_tokens:
|
|
375
|
+
values.append(
|
|
376
|
+
_format_optional_float(tps_map.get((model, "prefill", token)))
|
|
377
|
+
)
|
|
378
|
+
for token in decode_tokens:
|
|
379
|
+
values.append(_format_optional_float(tps_map.get((model, "decode", token))))
|
|
380
|
+
for token in prefill_tokens:
|
|
381
|
+
values.append(
|
|
382
|
+
_format_optional_float(time_map.get((model, "prefill", token)))
|
|
383
|
+
)
|
|
384
|
+
for token in decode_tokens:
|
|
385
|
+
values.append(
|
|
386
|
+
_format_optional_float(time_map.get((model, "decode", token)))
|
|
387
|
+
)
|
|
388
|
+
for token in prefill_tokens:
|
|
389
|
+
values.append(
|
|
390
|
+
_format_optional_float(npu_pct_map.get((model, "prefill", token)))
|
|
391
|
+
)
|
|
392
|
+
for token in decode_tokens:
|
|
393
|
+
values.append(
|
|
394
|
+
_format_optional_float(npu_pct_map.get((model, "decode", token)))
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
drow = device_map.get(model, {})
|
|
398
|
+
for col in device_cols:
|
|
399
|
+
v = drow.get(col) if isinstance(drow, Mapping) else None
|
|
400
|
+
values.append(_format_optional_float(v))
|
|
401
|
+
rows.append(values)
|
|
402
|
+
|
|
403
|
+
Path(path).write_text(markdown_table(headers, rows), encoding="utf-8")
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def existing_png_paths(
|
|
407
|
+
results_dir: Path | str, *, prefixes: Sequence[str] | None = None
|
|
408
|
+
) -> list[Path]:
|
|
409
|
+
"""Return sorted PNG paths under a benchmark results directory.
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
results_dir: Directory to scan.
|
|
413
|
+
prefixes: Optional filename prefixes to include.
|
|
414
|
+
|
|
415
|
+
Returns:
|
|
416
|
+
Sorted PNG files matching the optional prefixes.
|
|
417
|
+
"""
|
|
418
|
+
out_dir = Path(results_dir)
|
|
419
|
+
paths = sorted(
|
|
420
|
+
out_dir.glob("*.png"),
|
|
421
|
+
key=lambda path: (_plot_sort_key(path), path.name),
|
|
422
|
+
)
|
|
423
|
+
if prefixes is None:
|
|
424
|
+
return [path for path in paths if _plot_title(path) is not None]
|
|
425
|
+
prefix_tuple = tuple(prefixes)
|
|
426
|
+
return [path for path in paths if path.name.startswith(prefix_tuple)]
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
def _with_collection_metadata(payload: Any) -> dict[str, Any]:
|
|
430
|
+
collected_at = datetime.now().astimezone().isoformat(timespec="seconds")
|
|
431
|
+
if isinstance(payload, dict):
|
|
432
|
+
out = dict(payload)
|
|
433
|
+
out.setdefault("status", "ok")
|
|
434
|
+
out.setdefault("collected_at", collected_at)
|
|
435
|
+
return out
|
|
436
|
+
return {"status": "ok", "collected_at": collected_at, "data": payload}
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
def _host_info_markdown(path: Path | None) -> list[str]:
|
|
440
|
+
lines = ["## Host PC Info\n\n"]
|
|
441
|
+
if path is None or not path.is_file():
|
|
442
|
+
lines.append("Host PC info is not available.\n\n")
|
|
443
|
+
return lines
|
|
444
|
+
try:
|
|
445
|
+
with path.open("r", encoding="utf-8") as f:
|
|
446
|
+
payload = json.load(f)
|
|
447
|
+
except (OSError, json.JSONDecodeError) as e:
|
|
448
|
+
lines.append(f"Failed to read `{path.name}`: {e}\n\n")
|
|
449
|
+
return lines
|
|
450
|
+
|
|
451
|
+
sections = _host_info_sections(payload)
|
|
452
|
+
if not sections:
|
|
453
|
+
lines.append("Host PC info is empty.\n\n")
|
|
454
|
+
return lines
|
|
455
|
+
lines.append(f"Source: `{path.name}`\n\n")
|
|
456
|
+
for title, rows in sections:
|
|
457
|
+
if title == "NPU":
|
|
458
|
+
_append_npu_info_markdown(lines, rows)
|
|
459
|
+
else:
|
|
460
|
+
_append_host_info_table(lines, title, rows)
|
|
461
|
+
return lines
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def _host_infos_markdown(paths_by_label: Mapping[str, Path]) -> list[str]:
|
|
465
|
+
"""Render source-labeled host info JSON files as merged comparison tables."""
|
|
466
|
+
|
|
467
|
+
lines = ["## Host PC Info\n\n"]
|
|
468
|
+
if not paths_by_label:
|
|
469
|
+
lines.append("Host PC info is not available.\n\n")
|
|
470
|
+
return lines
|
|
471
|
+
|
|
472
|
+
metadata_rows: list[tuple[str, dict[str, str]]] = [("Source", {}), ("Status", {})]
|
|
473
|
+
sections_by_label: dict[str, dict[str, list[tuple[str, str]]]] = {}
|
|
474
|
+
section_order: list[str] = []
|
|
475
|
+
for label, path in paths_by_label.items():
|
|
476
|
+
metadata_rows[0][1][label] = path.as_posix()
|
|
477
|
+
if not path.is_file():
|
|
478
|
+
metadata_rows[1][1][label] = (
|
|
479
|
+
"missing: host_pc_info.json was not found in the input folder"
|
|
480
|
+
)
|
|
481
|
+
sections_by_label[label] = {}
|
|
482
|
+
continue
|
|
483
|
+
try:
|
|
484
|
+
with path.open("r", encoding="utf-8") as f:
|
|
485
|
+
payload = json.load(f)
|
|
486
|
+
except (OSError, json.JSONDecodeError) as e:
|
|
487
|
+
metadata_rows[1][1][label] = f"error: {e}"
|
|
488
|
+
sections_by_label[label] = {}
|
|
489
|
+
continue
|
|
490
|
+
|
|
491
|
+
sections = _host_info_sections(payload)
|
|
492
|
+
if not sections:
|
|
493
|
+
metadata_rows[1][1][label] = "empty"
|
|
494
|
+
sections_by_label[label] = {}
|
|
495
|
+
continue
|
|
496
|
+
metadata_rows[1][1][label] = "ok"
|
|
497
|
+
label_sections: dict[str, list[tuple[str, str]]] = {}
|
|
498
|
+
for title, rows in sections:
|
|
499
|
+
label_sections[title] = rows
|
|
500
|
+
if title not in section_order:
|
|
501
|
+
section_order.append(title)
|
|
502
|
+
sections_by_label[label] = label_sections
|
|
503
|
+
|
|
504
|
+
labels = list(paths_by_label)
|
|
505
|
+
_append_merged_host_info_table(lines, "Sources", labels, metadata_rows)
|
|
506
|
+
for section in section_order:
|
|
507
|
+
field_values: dict[str, dict[str, str]] = {}
|
|
508
|
+
for label in labels:
|
|
509
|
+
for field, value in sections_by_label.get(label, {}).get(section, []):
|
|
510
|
+
field_values.setdefault(field, {})[label] = value
|
|
511
|
+
rows = [(field, values) for field, values in field_values.items()]
|
|
512
|
+
_append_merged_host_info_table(lines, section, labels, rows)
|
|
513
|
+
return lines
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
def _append_merged_host_info_table(
|
|
517
|
+
lines: list[str],
|
|
518
|
+
title: str,
|
|
519
|
+
labels: Sequence[str],
|
|
520
|
+
rows: Sequence[tuple[str, Mapping[str, str]]],
|
|
521
|
+
) -> None:
|
|
522
|
+
"""Append a source-merged host info table."""
|
|
523
|
+
|
|
524
|
+
lines.append(f"### {title}\n\n")
|
|
525
|
+
lines.append(
|
|
526
|
+
"| Field | " + " | ".join(_escape_markdown(label) for label in labels) + " |\n"
|
|
527
|
+
)
|
|
528
|
+
lines.append("| --- | " + " | ".join("---" for _ in labels) + " |\n")
|
|
529
|
+
for field, values_by_label in rows:
|
|
530
|
+
values = [_escape_markdown(values_by_label.get(label, "")) for label in labels]
|
|
531
|
+
lines.append(f"| `{_escape_markdown(field)}` | " + " | ".join(values) + " |\n")
|
|
532
|
+
lines.append("\n")
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
def _plots_markdown(
|
|
536
|
+
base_dir: Path,
|
|
537
|
+
plot_paths: Sequence[Path],
|
|
538
|
+
*,
|
|
539
|
+
plot_tables: Mapping[str, str] | None = None,
|
|
540
|
+
) -> list[str]:
|
|
541
|
+
lines = ["## Plots\n\n"]
|
|
542
|
+
existing = [path for path in plot_paths if path.is_file()]
|
|
543
|
+
if not existing:
|
|
544
|
+
lines.append("No plot PNG files were generated.\n\n")
|
|
545
|
+
return lines
|
|
546
|
+
tables = plot_tables or {}
|
|
547
|
+
for path in existing:
|
|
548
|
+
rel = path.relative_to(base_dir) if path.is_relative_to(base_dir) else path
|
|
549
|
+
title = _plot_title(path) or path.stem.replace("_", " ").title()
|
|
550
|
+
lines.append(f"### {title}\n\n")
|
|
551
|
+
lines.append(f"})\n\n")
|
|
552
|
+
table = tables.get(path.name)
|
|
553
|
+
if table:
|
|
554
|
+
lines.append(table)
|
|
555
|
+
if not lines[-1].endswith("\n"):
|
|
556
|
+
lines.append("\n")
|
|
557
|
+
lines.append("\n")
|
|
558
|
+
return lines
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
def _plot_title(path: Path) -> str | None:
|
|
562
|
+
title = _PLOT_TITLES_BY_NAME.get(path.name)
|
|
563
|
+
if title is not None:
|
|
564
|
+
return title
|
|
565
|
+
|
|
566
|
+
stem = path.stem
|
|
567
|
+
if stem.startswith("rtf_beams"):
|
|
568
|
+
return "Real-Time Factor"
|
|
569
|
+
if stem.startswith("wer_beams"):
|
|
570
|
+
return "Word Error Rate"
|
|
571
|
+
if stem.startswith("cer_beams"):
|
|
572
|
+
return "Character Error Rate"
|
|
573
|
+
return None
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
def _plot_sort_key(path: Path) -> int:
|
|
577
|
+
if path.name in _PLOT_NAME_ORDER:
|
|
578
|
+
return _PLOT_NAME_ORDER[path.name]
|
|
579
|
+
stem = path.stem
|
|
580
|
+
if stem.startswith("rtf_beams"):
|
|
581
|
+
return len(_PLOT_NAME_ORDER)
|
|
582
|
+
if stem.startswith("wer_beams"):
|
|
583
|
+
return len(_PLOT_NAME_ORDER) + 1
|
|
584
|
+
if stem.startswith("cer_beams"):
|
|
585
|
+
return len(_PLOT_NAME_ORDER) + 2
|
|
586
|
+
return len(_PLOT_NAME_ORDER) + 100
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
def _host_info_sections(payload: Any) -> list[tuple[str, list[tuple[str, str]]]]:
|
|
590
|
+
rows = _flatten_json(payload)
|
|
591
|
+
if not rows:
|
|
592
|
+
return []
|
|
593
|
+
|
|
594
|
+
grouped: dict[str, list[tuple[str, str]]] = {
|
|
595
|
+
section: [] for section in _HOST_INFO_SECTION_ORDER
|
|
596
|
+
}
|
|
597
|
+
general_rows: list[tuple[str, str]] = []
|
|
598
|
+
for key, value in rows:
|
|
599
|
+
section = _host_info_section_for_key(key)
|
|
600
|
+
if section is None:
|
|
601
|
+
general_rows.append((key, value))
|
|
602
|
+
else:
|
|
603
|
+
grouped[section].append((key, value))
|
|
604
|
+
|
|
605
|
+
sections: list[tuple[str, list[tuple[str, str]]]] = []
|
|
606
|
+
if general_rows:
|
|
607
|
+
sections.append(("General", general_rows))
|
|
608
|
+
sections.extend(
|
|
609
|
+
(section, grouped[section])
|
|
610
|
+
for section in _HOST_INFO_SECTION_ORDER
|
|
611
|
+
if grouped[section]
|
|
612
|
+
)
|
|
613
|
+
return sections
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
def _append_host_info_table(
|
|
617
|
+
lines: list[str],
|
|
618
|
+
title: str,
|
|
619
|
+
rows: Sequence[tuple[str, str]],
|
|
620
|
+
*,
|
|
621
|
+
heading_level: int = 3,
|
|
622
|
+
) -> None:
|
|
623
|
+
"""Append one host info section as a Markdown table."""
|
|
624
|
+
lines.append(f"{'#' * heading_level} {title}\n\n")
|
|
625
|
+
_append_field_value_table(lines, rows)
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
def _append_npu_info_markdown(
|
|
629
|
+
lines: list[str], rows: Sequence[tuple[str, str]], *, heading_level: int = 3
|
|
630
|
+
) -> None:
|
|
631
|
+
"""Append NPU host info with ``npus`` array entries grouped by index."""
|
|
632
|
+
common_rows: list[tuple[str, str]] = []
|
|
633
|
+
indexed_rows: dict[int, list[tuple[str, str]]] = {}
|
|
634
|
+
for key, value in rows:
|
|
635
|
+
npu_key = _split_npu_array_key(key)
|
|
636
|
+
if npu_key is None:
|
|
637
|
+
common_rows.append((key, value))
|
|
638
|
+
continue
|
|
639
|
+
index, field = npu_key
|
|
640
|
+
indexed_rows.setdefault(index, []).append((field, value))
|
|
641
|
+
|
|
642
|
+
if not indexed_rows:
|
|
643
|
+
_append_host_info_table(lines, "NPU", rows, heading_level=heading_level)
|
|
644
|
+
return
|
|
645
|
+
|
|
646
|
+
lines.append(f"{'#' * heading_level} NPU\n\n")
|
|
647
|
+
if common_rows:
|
|
648
|
+
lines.append(f"{'#' * (heading_level + 1)} General\n\n")
|
|
649
|
+
_append_field_value_table(lines, common_rows)
|
|
650
|
+
for index in sorted(indexed_rows):
|
|
651
|
+
lines.append(f"{'#' * (heading_level + 1)} NPU {index}\n\n")
|
|
652
|
+
_append_field_value_table(lines, indexed_rows[index])
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
def _append_field_value_table(
|
|
656
|
+
lines: list[str], rows: Sequence[tuple[str, str]]
|
|
657
|
+
) -> None:
|
|
658
|
+
"""Append field/value rows as a Markdown table."""
|
|
659
|
+
lines.append("| Field | Value |\n")
|
|
660
|
+
lines.append("| --- | --- |\n")
|
|
661
|
+
for key, value in rows:
|
|
662
|
+
lines.append(f"| `{_escape_markdown(key)}` | {_escape_markdown(value)} |\n")
|
|
663
|
+
lines.append("\n")
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
def _host_info_section_for_key(key: str) -> str | None:
|
|
667
|
+
if _split_npu_array_key(key) is not None:
|
|
668
|
+
return "NPU"
|
|
669
|
+
normalized = key.replace("_", ".").replace("-", ".").replace(" ", ".").lower()
|
|
670
|
+
parts = [
|
|
671
|
+
part
|
|
672
|
+
for part in normalized.replace("[", ".").replace("]", ".").split(".")
|
|
673
|
+
if part
|
|
674
|
+
]
|
|
675
|
+
for part in parts:
|
|
676
|
+
section = _HOST_INFO_SECTION_ALIASES.get(part)
|
|
677
|
+
if section is not None:
|
|
678
|
+
return section
|
|
679
|
+
return None
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
def _split_npu_array_key(key: str) -> tuple[int, str] | None:
|
|
683
|
+
"""Return the NPU array index and field for flattened ``npus`` keys."""
|
|
684
|
+
match = _NPU_ARRAY_KEY_RE.search(key)
|
|
685
|
+
if match is None:
|
|
686
|
+
return None
|
|
687
|
+
return int(match.group(1)), match.group(2)
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
def _host_info_section_title(value: str) -> str:
|
|
691
|
+
upper_names = {"cpu": "CPU", "dram": "DRAM", "gpu": "GPU", "npu": "NPU", "os": "OS"}
|
|
692
|
+
normalized = value.replace("_", " ").replace("-", " ").strip()
|
|
693
|
+
lowered = normalized.lower()
|
|
694
|
+
if lowered in upper_names:
|
|
695
|
+
return upper_names[lowered]
|
|
696
|
+
return " ".join(
|
|
697
|
+
upper_names.get(part.lower(), part.capitalize()) for part in normalized.split()
|
|
698
|
+
)
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
def _table_markdown(path: Path | None) -> list[str]:
|
|
702
|
+
lines = ["## Results Table\n\n"]
|
|
703
|
+
if path is None or not path.is_file():
|
|
704
|
+
lines.append("Results table is not available.\n")
|
|
705
|
+
return lines
|
|
706
|
+
lines.append(path.read_text(encoding="utf-8"))
|
|
707
|
+
if not lines[-1].endswith("\n"):
|
|
708
|
+
lines.append("\n")
|
|
709
|
+
return lines
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
def _flatten_json(value: Any, *, prefix: str = "") -> list[tuple[str, str]]:
|
|
713
|
+
if isinstance(value, Mapping):
|
|
714
|
+
rows: list[tuple[str, str]] = []
|
|
715
|
+
for key, child in value.items():
|
|
716
|
+
child_key = f"{prefix}.{key}" if prefix else str(key)
|
|
717
|
+
rows.extend(_flatten_json(child, prefix=child_key))
|
|
718
|
+
return rows
|
|
719
|
+
if isinstance(value, list):
|
|
720
|
+
if all(not isinstance(item, (Mapping, list)) for item in value):
|
|
721
|
+
return [(prefix, ", ".join(_scalar_to_text(item) for item in value))]
|
|
722
|
+
rows = []
|
|
723
|
+
for idx, child in enumerate(value):
|
|
724
|
+
rows.extend(_flatten_json(child, prefix=f"{prefix}[{idx}]"))
|
|
725
|
+
return rows
|
|
726
|
+
return [(prefix, _scalar_to_text(value))] if prefix else []
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
def _scalar_to_text(value: Any) -> str:
|
|
730
|
+
if value is None:
|
|
731
|
+
return ""
|
|
732
|
+
if isinstance(value, (str, int, float, bool)):
|
|
733
|
+
return str(value)
|
|
734
|
+
return json.dumps(value, ensure_ascii=False)
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
def _format_summary_cell(value: Any) -> str:
|
|
738
|
+
"""Format one benchmark summary table value."""
|
|
739
|
+
if value is None or value == "":
|
|
740
|
+
return ""
|
|
741
|
+
if isinstance(value, (int, float)):
|
|
742
|
+
return f"{float(value):.6f}"
|
|
743
|
+
if isinstance(value, str):
|
|
744
|
+
try:
|
|
745
|
+
return f"{float(value):.6f}"
|
|
746
|
+
except ValueError:
|
|
747
|
+
return _escape_markdown(value)
|
|
748
|
+
return _escape_markdown(str(value))
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
def _format_optional_float(value: Any) -> str:
|
|
752
|
+
"""Format a numeric value for compact benchmark tables."""
|
|
753
|
+
return f"{float(value):.6f}" if isinstance(value, (int, float)) else ""
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
def _is_int_like(value: Any) -> bool:
|
|
757
|
+
"""Return whether a value can be losslessly parsed as an integer token count."""
|
|
758
|
+
if isinstance(value, int):
|
|
759
|
+
return True
|
|
760
|
+
if isinstance(value, str):
|
|
761
|
+
try:
|
|
762
|
+
int(value)
|
|
763
|
+
except ValueError:
|
|
764
|
+
return False
|
|
765
|
+
return True
|
|
766
|
+
return False
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
def _escape_markdown(value: str) -> str:
|
|
770
|
+
return value.replace("|", "\\|").replace("\n", "<br>")
|