ultralytics 8.2.9__tar.gz → 8.2.11__tar.gz
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.
Potentially problematic release.
This version of ultralytics might be problematic. Click here for more details.
- {ultralytics-8.2.9/ultralytics.egg-info → ultralytics-8.2.11}/PKG-INFO +2 -2
- {ultralytics-8.2.9 → ultralytics-8.2.11}/pyproject.toml +1 -1
- {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_cli.py +2 -2
- {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_cuda.py +32 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_exports.py +76 -17
- {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_python.py +21 -36
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/__init__.py +1 -1
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/__init__.py +1 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/base.py +1 -1
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/exporter.py +80 -19
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/results.py +22 -16
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/model.py +3 -3
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/checks.py +1 -1
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/downloads.py +1 -1
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/tuner.py +1 -1
- {ultralytics-8.2.9 → ultralytics-8.2.11/ultralytics.egg-info}/PKG-INFO +2 -2
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics.egg-info/requires.txt +1 -1
- {ultralytics-8.2.9 → ultralytics-8.2.11}/LICENSE +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/README.md +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/setup.cfg +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_engine.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_explorer.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_integrations.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/assets/bus.jpg +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/assets/zidane.jpg +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/Argoverse.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/DOTAv1.5.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/DOTAv1.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/GlobalWheat2020.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/ImageNet.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/Objects365.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/SKU-110K.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/VOC.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/VisDrone.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/african-wildlife.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/brain-tumor.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/carparts-seg.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco-pose.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco128-seg.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco128.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco8-pose.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco8-seg.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco8.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/crack-seg.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/dota8.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/lvis.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/open-images-v7.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/package-seg.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/tiger-pose.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/xView.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/default.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v3/yolov3-spp.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v3/yolov3-tiny.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v3/yolov3.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v5/yolov5-p6.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v5/yolov5.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v6/yolov6.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-cls.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-ghost.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-obb.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-p2.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-p6.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-pose.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-seg.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-world.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-worldv2.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v9/yolov9c-seg.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v9/yolov9c.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v9/yolov9e-seg.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v9/yolov9e.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/trackers/botsort.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/trackers/bytetrack.yaml +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/annotator.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/augment.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/build.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/converter.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/dataset.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/explorer/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/explorer/explorer.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/explorer/gui/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/explorer/gui/dash.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/explorer/utils.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/loaders.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/split_dota.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/utils.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/model.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/predictor.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/trainer.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/tuner.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/validator.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/hub/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/hub/auth.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/hub/session.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/hub/utils.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/model.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/predict.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/prompt.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/utils.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/val.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/nas/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/nas/model.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/nas/predict.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/nas/val.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/rtdetr/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/rtdetr/model.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/rtdetr/predict.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/rtdetr/train.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/rtdetr/val.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/amg.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/build.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/model.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/decoders.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/encoders.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/sam.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/tiny_encoder.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/transformer.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/predict.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/utils/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/utils/loss.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/utils/ops.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/classify/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/classify/predict.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/classify/train.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/classify/val.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/detect/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/detect/predict.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/detect/train.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/detect/val.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/obb/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/obb/predict.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/obb/train.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/obb/val.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/pose/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/pose/predict.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/pose/train.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/pose/val.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/segment/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/segment/predict.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/segment/train.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/segment/val.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/world/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/world/train.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/world/train_world.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/autobackend.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/block.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/conv.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/head.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/transformer.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/utils.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/tasks.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/ai_gym.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/distance_calculation.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/heatmap.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/object_counter.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/parking_management.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/queue_management.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/speed_estimation.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/basetrack.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/bot_sort.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/byte_tracker.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/track.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/utils/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/utils/gmc.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/utils/kalman_filter.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/utils/matching.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/autobatch.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/benchmarks.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/__init__.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/base.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/clearml.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/comet.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/dvc.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/hub.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/mlflow.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/neptune.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/raytune.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/tensorboard.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/wb.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/dist.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/errors.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/files.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/instance.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/loss.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/metrics.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/ops.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/patches.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/plotting.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/tal.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/torch_utils.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/triton.py +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics.egg-info/SOURCES.txt +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics.egg-info/dependency_links.txt +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics.egg-info/entry_points.txt +0 -0
- {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ultralytics
|
|
3
|
-
Version: 8.2.
|
|
3
|
+
Version: 8.2.11
|
|
4
4
|
Summary: Ultralytics YOLOv8 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
|
|
5
5
|
Author: Glenn Jocher, Ayush Chaurasia, Jing Qiu
|
|
6
6
|
Maintainer: Glenn Jocher, Ayush Chaurasia, Jing Qiu
|
|
@@ -77,7 +77,7 @@ Requires-Dist: dvclive>=2.12.0; extra == "logging"
|
|
|
77
77
|
Provides-Extra: extra
|
|
78
78
|
Requires-Dist: hub-sdk>=0.0.5; extra == "extra"
|
|
79
79
|
Requires-Dist: ipython; extra == "extra"
|
|
80
|
-
Requires-Dist: albumentations
|
|
80
|
+
Requires-Dist: albumentations>=1.4.6; extra == "extra"
|
|
81
81
|
Requires-Dist: pycocotools>=2.0.7; extra == "extra"
|
|
82
82
|
|
|
83
83
|
<div align="center">
|
|
@@ -123,7 +123,7 @@ logging = [
|
|
|
123
123
|
extra = [
|
|
124
124
|
"hub-sdk>=0.0.5", # Ultralytics HUB
|
|
125
125
|
"ipython", # interactive notebook
|
|
126
|
-
"albumentations>=1.
|
|
126
|
+
"albumentations>=1.4.6", # training augmentations
|
|
127
127
|
"pycocotools>=2.0.7", # COCO mAP
|
|
128
128
|
]
|
|
129
129
|
|
|
@@ -54,8 +54,8 @@ def test_export(model):
|
|
|
54
54
|
|
|
55
55
|
def test_rtdetr(task="detect", model="yolov8n-rtdetr.yaml", data="coco8.yaml"):
|
|
56
56
|
"""Test the RTDETR functionality with the Ultralytics framework."""
|
|
57
|
-
# Warning:
|
|
58
|
-
run(f"yolo train {task} model={model} data={data} --imgsz= 160 epochs =1, cache = disk")
|
|
57
|
+
# Warning: must use imgsz=640 (note also add coma, spaces, fraction=0.25 args to test single-image training)
|
|
58
|
+
run(f"yolo train {task} model={model} data={data} --imgsz= 160 epochs =1, cache = disk fraction=0.25")
|
|
59
59
|
run(f"yolo predict {task} model={model} source={ASSETS / 'bus.jpg'} imgsz=160 save save_crop save_txt")
|
|
60
60
|
|
|
61
61
|
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
|
2
2
|
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from itertools import product
|
|
5
|
+
|
|
3
6
|
import pytest
|
|
4
7
|
import torch
|
|
5
8
|
|
|
6
9
|
from ultralytics import YOLO
|
|
7
10
|
from ultralytics.utils import ASSETS, WEIGHTS_DIR
|
|
11
|
+
from ultralytics.cfg import TASK2DATA, TASK2MODEL, TASKS
|
|
8
12
|
|
|
9
13
|
from . import CUDA_DEVICE_COUNT, CUDA_IS_AVAILABLE, MODEL, SOURCE
|
|
10
14
|
|
|
@@ -23,6 +27,34 @@ def test_export_engine():
|
|
|
23
27
|
YOLO(f)(SOURCE, device=0)
|
|
24
28
|
|
|
25
29
|
|
|
30
|
+
@pytest.mark.slow
|
|
31
|
+
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason="CUDA is not available")
|
|
32
|
+
@pytest.mark.parametrize(
|
|
33
|
+
"task, dynamic, int8, half, batch",
|
|
34
|
+
[ # generate all combinations but exclude those where both int8 and half are True
|
|
35
|
+
(task, dynamic, int8, half, batch)
|
|
36
|
+
# Note: tests reduced below pending compute availability expansion as GPU CI runner utilization is high
|
|
37
|
+
# for task, dynamic, int8, half, batch in product(TASKS, [True, False], [True, False], [True, False], [1, 2])
|
|
38
|
+
for task, dynamic, int8, half, batch in product(TASKS, [True], [True], [False], [2])
|
|
39
|
+
if not (int8 and half) # exclude cases where both int8 and half are True
|
|
40
|
+
],
|
|
41
|
+
)
|
|
42
|
+
def test_export_engine_matrix(task, dynamic, int8, half, batch):
|
|
43
|
+
"""Test YOLO exports to TensorRT format."""
|
|
44
|
+
file = YOLO(TASK2MODEL[task]).export(
|
|
45
|
+
format="engine",
|
|
46
|
+
imgsz=32,
|
|
47
|
+
dynamic=dynamic,
|
|
48
|
+
int8=int8,
|
|
49
|
+
half=half,
|
|
50
|
+
batch=batch,
|
|
51
|
+
data=TASK2DATA[task],
|
|
52
|
+
)
|
|
53
|
+
YOLO(file)([SOURCE] * batch, imgsz=64 if dynamic else 32) # exported model inference
|
|
54
|
+
Path(file).unlink() # cleanup
|
|
55
|
+
Path(file).with_suffix(".cache").unlink() if int8 else None # cleanup INT8 cache
|
|
56
|
+
|
|
57
|
+
|
|
26
58
|
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason="CUDA is not available")
|
|
27
59
|
def test_train():
|
|
28
60
|
"""Test model training on a minimal dataset."""
|
|
@@ -18,24 +18,18 @@ from ultralytics.utils import (
|
|
|
18
18
|
checks,
|
|
19
19
|
)
|
|
20
20
|
from ultralytics.utils.torch_utils import TORCH_1_9, TORCH_1_13
|
|
21
|
-
from . import MODEL, SOURCE
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
EXPORT_PARAMETERS_LIST = [ # generate all combinations but exclude those where both int8 and half are True
|
|
25
|
-
(task, dynamic, int8, half, batch)
|
|
26
|
-
for task, dynamic, int8, half, batch in product(TASKS, [True, False], [True, False], [True, False], [1, 2])
|
|
27
|
-
if not (int8 and half) # exclude cases where both int8 and half are True
|
|
28
|
-
]
|
|
22
|
+
from . import MODEL, SOURCE
|
|
29
23
|
|
|
30
24
|
|
|
31
25
|
def test_export_torchscript():
|
|
32
|
-
"""Test
|
|
26
|
+
"""Test YOLO exports to TorchScript format."""
|
|
33
27
|
f = YOLO(MODEL).export(format="torchscript", optimize=False, imgsz=32)
|
|
34
28
|
YOLO(f)(SOURCE, imgsz=32) # exported model inference
|
|
35
29
|
|
|
36
30
|
|
|
37
31
|
def test_export_onnx():
|
|
38
|
-
"""Test
|
|
32
|
+
"""Test YOLO exports to ONNX format."""
|
|
39
33
|
f = YOLO(MODEL).export(format="onnx", dynamic=True, imgsz=32)
|
|
40
34
|
YOLO(f)(SOURCE, imgsz=32) # exported model inference
|
|
41
35
|
|
|
@@ -43,7 +37,7 @@ def test_export_onnx():
|
|
|
43
37
|
@pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="OpenVINO not supported in Python 3.12")
|
|
44
38
|
@pytest.mark.skipif(not TORCH_1_13, reason="OpenVINO requires torch>=1.13")
|
|
45
39
|
def test_export_openvino():
|
|
46
|
-
"""Test
|
|
40
|
+
"""Test YOLO exports to OpenVINO format."""
|
|
47
41
|
f = YOLO(MODEL).export(format="openvino", imgsz=32)
|
|
48
42
|
YOLO(f)(SOURCE, imgsz=32) # exported model inference
|
|
49
43
|
|
|
@@ -51,9 +45,16 @@ def test_export_openvino():
|
|
|
51
45
|
@pytest.mark.slow
|
|
52
46
|
@pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="OpenVINO not supported in Python 3.12")
|
|
53
47
|
@pytest.mark.skipif(not TORCH_1_13, reason="OpenVINO requires torch>=1.13")
|
|
54
|
-
@pytest.mark.parametrize(
|
|
48
|
+
@pytest.mark.parametrize(
|
|
49
|
+
"task, dynamic, int8, half, batch",
|
|
50
|
+
[ # generate all combinations but exclude those where both int8 and half are True
|
|
51
|
+
(task, dynamic, int8, half, batch)
|
|
52
|
+
for task, dynamic, int8, half, batch in product(TASKS, [True, False], [True, False], [True, False], [1, 2])
|
|
53
|
+
if not (int8 and half) # exclude cases where both int8 and half are True
|
|
54
|
+
],
|
|
55
|
+
)
|
|
55
56
|
def test_export_openvino_matrix(task, dynamic, int8, half, batch):
|
|
56
|
-
"""Test
|
|
57
|
+
"""Test YOLO exports to OpenVINO format."""
|
|
57
58
|
file = YOLO(TASK2MODEL[task]).export(
|
|
58
59
|
format="openvino",
|
|
59
60
|
imgsz=32,
|
|
@@ -73,12 +74,70 @@ def test_export_openvino_matrix(task, dynamic, int8, half, batch):
|
|
|
73
74
|
shutil.rmtree(file)
|
|
74
75
|
|
|
75
76
|
|
|
77
|
+
@pytest.mark.slow
|
|
78
|
+
@pytest.mark.parametrize("task, dynamic, int8, half, batch", product(TASKS, [True, False], [False], [False], [1, 2]))
|
|
79
|
+
def test_export_onnx_matrix(task, dynamic, int8, half, batch):
|
|
80
|
+
"""Test YOLO exports to ONNX format."""
|
|
81
|
+
file = YOLO(TASK2MODEL[task]).export(
|
|
82
|
+
format="onnx",
|
|
83
|
+
imgsz=32,
|
|
84
|
+
dynamic=dynamic,
|
|
85
|
+
int8=int8,
|
|
86
|
+
half=half,
|
|
87
|
+
batch=batch,
|
|
88
|
+
)
|
|
89
|
+
YOLO(file)([SOURCE] * batch, imgsz=64 if dynamic else 32) # exported model inference
|
|
90
|
+
Path(file).unlink() # cleanup
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@pytest.mark.slow
|
|
94
|
+
@pytest.mark.parametrize("task, dynamic, int8, half, batch", product(TASKS, [False], [False], [False], [1, 2]))
|
|
95
|
+
def test_export_torchscript_matrix(task, dynamic, int8, half, batch):
|
|
96
|
+
"""Test YOLO exports to TorchScript format."""
|
|
97
|
+
file = YOLO(TASK2MODEL[task]).export(
|
|
98
|
+
format="torchscript",
|
|
99
|
+
imgsz=32,
|
|
100
|
+
dynamic=dynamic,
|
|
101
|
+
int8=int8,
|
|
102
|
+
half=half,
|
|
103
|
+
batch=batch,
|
|
104
|
+
)
|
|
105
|
+
YOLO(file)([SOURCE] * 3, imgsz=64 if dynamic else 32) # exported model inference at batch=3
|
|
106
|
+
Path(file).unlink() # cleanup
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@pytest.mark.slow
|
|
110
|
+
@pytest.mark.skipif(not MACOS, reason="CoreML inference only supported on macOS")
|
|
111
|
+
@pytest.mark.skipif(not TORCH_1_9, reason="CoreML>=7.2 not supported with PyTorch<=1.8")
|
|
112
|
+
@pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="CoreML not supported in Python 3.12")
|
|
113
|
+
@pytest.mark.parametrize(
|
|
114
|
+
"task, dynamic, int8, half, batch",
|
|
115
|
+
[ # generate all combinations but exclude those where both int8 and half are True
|
|
116
|
+
(task, dynamic, int8, half, batch)
|
|
117
|
+
for task, dynamic, int8, half, batch in product(TASKS, [False], [True, False], [True, False], [1])
|
|
118
|
+
if not (int8 and half) # exclude cases where both int8 and half are True
|
|
119
|
+
],
|
|
120
|
+
)
|
|
121
|
+
def test_export_coreml_matrix(task, dynamic, int8, half, batch):
|
|
122
|
+
"""Test YOLO exports to TorchScript format."""
|
|
123
|
+
file = YOLO(TASK2MODEL[task]).export(
|
|
124
|
+
format="coreml",
|
|
125
|
+
imgsz=32,
|
|
126
|
+
dynamic=dynamic,
|
|
127
|
+
int8=int8,
|
|
128
|
+
half=half,
|
|
129
|
+
batch=batch,
|
|
130
|
+
)
|
|
131
|
+
YOLO(file)([SOURCE] * batch, imgsz=32) # exported model inference at batch=3
|
|
132
|
+
shutil.rmtree(file) # cleanup
|
|
133
|
+
|
|
134
|
+
|
|
76
135
|
@pytest.mark.skipif(not TORCH_1_9, reason="CoreML>=7.2 not supported with PyTorch<=1.8")
|
|
77
136
|
@pytest.mark.skipif(WINDOWS, reason="CoreML not supported on Windows") # RuntimeError: BlobWriter not loaded
|
|
78
137
|
@pytest.mark.skipif(IS_RASPBERRYPI, reason="CoreML not supported on Raspberry Pi")
|
|
79
138
|
@pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="CoreML not supported in Python 3.12")
|
|
80
139
|
def test_export_coreml():
|
|
81
|
-
"""Test
|
|
140
|
+
"""Test YOLO exports to CoreML format."""
|
|
82
141
|
if MACOS:
|
|
83
142
|
f = YOLO(MODEL).export(format="coreml", imgsz=32)
|
|
84
143
|
YOLO(f)(SOURCE, imgsz=32) # model prediction only supported on macOS for nms=False models
|
|
@@ -89,7 +148,7 @@ def test_export_coreml():
|
|
|
89
148
|
@pytest.mark.skipif(not LINUX, reason="Test disabled as TF suffers from install conflicts on Windows and macOS")
|
|
90
149
|
def test_export_tflite():
|
|
91
150
|
"""
|
|
92
|
-
Test
|
|
151
|
+
Test YOLO exports to TFLite format.
|
|
93
152
|
|
|
94
153
|
Note TF suffers from install conflicts on Windows and macOS.
|
|
95
154
|
"""
|
|
@@ -102,7 +161,7 @@ def test_export_tflite():
|
|
|
102
161
|
@pytest.mark.skipif(not LINUX, reason="TF suffers from install conflicts on Windows and macOS")
|
|
103
162
|
def test_export_pb():
|
|
104
163
|
"""
|
|
105
|
-
Test
|
|
164
|
+
Test YOLO exports to *.pb format.
|
|
106
165
|
|
|
107
166
|
Note TF suffers from install conflicts on Windows and macOS.
|
|
108
167
|
"""
|
|
@@ -114,7 +173,7 @@ def test_export_pb():
|
|
|
114
173
|
@pytest.mark.skipif(True, reason="Test disabled as Paddle protobuf and ONNX protobuf requirementsk conflict.")
|
|
115
174
|
def test_export_paddle():
|
|
116
175
|
"""
|
|
117
|
-
Test
|
|
176
|
+
Test YOLO exports to Paddle format.
|
|
118
177
|
|
|
119
178
|
Note Paddle protobuf requirements conflicting with onnx protobuf requirements.
|
|
120
179
|
"""
|
|
@@ -123,6 +182,6 @@ def test_export_paddle():
|
|
|
123
182
|
|
|
124
183
|
@pytest.mark.slow
|
|
125
184
|
def test_export_ncnn():
|
|
126
|
-
"""Test
|
|
185
|
+
"""Test YOLO exports to NCNN format."""
|
|
127
186
|
f = YOLO(MODEL).export(format="ncnn", imgsz=32)
|
|
128
187
|
YOLO(f)(SOURCE, imgsz=32) # exported model inference
|
|
@@ -12,7 +12,7 @@ import yaml
|
|
|
12
12
|
from PIL import Image
|
|
13
13
|
|
|
14
14
|
from ultralytics import RTDETR, YOLO
|
|
15
|
-
from ultralytics.cfg import TASK2DATA
|
|
15
|
+
from ultralytics.cfg import MODELS, TASK2DATA
|
|
16
16
|
from ultralytics.data.build import load_inference_source
|
|
17
17
|
from ultralytics.utils import (
|
|
18
18
|
ASSETS,
|
|
@@ -76,42 +76,27 @@ def test_predict_txt():
|
|
|
76
76
|
_ = YOLO(MODEL)(source=txt_file, imgsz=32)
|
|
77
77
|
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
@pytest.mark.parametrize("model_name", MODELS)
|
|
80
|
+
def test_predict_img(model_name):
|
|
80
81
|
"""Test YOLO prediction on various types of image sources."""
|
|
81
|
-
model = YOLO(
|
|
82
|
-
|
|
83
|
-
cls_model = YOLO(WEIGHTS_DIR / "yolov8n-cls.pt")
|
|
84
|
-
pose_model = YOLO(WEIGHTS_DIR / "yolov8n-pose.pt")
|
|
85
|
-
obb_model = YOLO(WEIGHTS_DIR / "yolov8n-obb.pt")
|
|
86
|
-
im = cv2.imread(str(SOURCE))
|
|
82
|
+
model = YOLO(WEIGHTS_DIR / model_name)
|
|
83
|
+
im = cv2.imread(str(SOURCE)) # uint8 numpy array
|
|
87
84
|
assert len(model(source=Image.open(SOURCE), save=True, verbose=True, imgsz=32)) == 1 # PIL
|
|
88
85
|
assert len(model(source=im, save=True, save_txt=True, imgsz=32)) == 1 # ndarray
|
|
86
|
+
assert len(model(torch.rand((2, 3, 32, 32)), imgsz=32)) == 2 # batch-size 2 Tensor, FP32 0.0-1.0 RGB order
|
|
89
87
|
assert len(model(source=[im, im], save=True, save_txt=True, imgsz=32)) == 2 # batch
|
|
90
88
|
assert len(list(model(source=[im, im], save=True, stream=True, imgsz=32))) == 2 # stream
|
|
91
|
-
assert len(model(torch.zeros(320, 640, 3).numpy(), imgsz=32)) == 1 # tensor to numpy
|
|
89
|
+
assert len(model(torch.zeros(320, 640, 3).numpy().astype(np.uint8), imgsz=32)) == 1 # tensor to numpy
|
|
92
90
|
batch = [
|
|
93
91
|
str(SOURCE), # filename
|
|
94
92
|
Path(SOURCE), # Path
|
|
95
93
|
"https://ultralytics.com/images/zidane.jpg" if ONLINE else SOURCE, # URI
|
|
96
94
|
cv2.imread(str(SOURCE)), # OpenCV
|
|
97
95
|
Image.open(SOURCE), # PIL
|
|
98
|
-
np.zeros((320, 640, 3)),
|
|
99
|
-
]
|
|
96
|
+
np.zeros((320, 640, 3), dtype=np.uint8), # numpy
|
|
97
|
+
]
|
|
100
98
|
assert len(model(batch, imgsz=32)) == len(batch) # multiple sources in a batch
|
|
101
99
|
|
|
102
|
-
# Test tensor inference
|
|
103
|
-
im = torch.rand((4, 3, 32, 32)) # batch-size 4, FP32 0.0-1.0 RGB order
|
|
104
|
-
results = model(im, imgsz=32)
|
|
105
|
-
assert len(results) == im.shape[0]
|
|
106
|
-
results = seg_model(im, imgsz=32)
|
|
107
|
-
assert len(results) == im.shape[0]
|
|
108
|
-
results = cls_model(im, imgsz=32)
|
|
109
|
-
assert len(results) == im.shape[0]
|
|
110
|
-
results = pose_model(im, imgsz=32)
|
|
111
|
-
assert len(results) == im.shape[0]
|
|
112
|
-
results = obb_model(im, imgsz=32)
|
|
113
|
-
assert len(results) == im.shape[0]
|
|
114
|
-
|
|
115
100
|
|
|
116
101
|
def test_predict_grey_and_4ch():
|
|
117
102
|
"""Test YOLO prediction on SOURCE converted to greyscale and 4-channel images."""
|
|
@@ -236,19 +221,19 @@ def test_predict_callback_and_setup():
|
|
|
236
221
|
print(boxes)
|
|
237
222
|
|
|
238
223
|
|
|
239
|
-
|
|
224
|
+
@pytest.mark.parametrize("model", MODELS)
|
|
225
|
+
def test_results(model):
|
|
240
226
|
"""Test various result formats for the YOLO model."""
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
print(r, len(r), r.path)
|
|
227
|
+
results = YOLO(WEIGHTS_DIR / model)([SOURCE, SOURCE], imgsz=160)
|
|
228
|
+
for r in results:
|
|
229
|
+
r = r.cpu().numpy()
|
|
230
|
+
r = r.to(device="cpu", dtype=torch.float32)
|
|
231
|
+
r.save_txt(txt_file=TMP / "runs/tests/label.txt", save_conf=True)
|
|
232
|
+
r.save_crop(save_dir=TMP / "runs/tests/crops/")
|
|
233
|
+
r.tojson(normalize=True)
|
|
234
|
+
r.plot(pil=True)
|
|
235
|
+
r.plot(conf=True, boxes=True)
|
|
236
|
+
print(r, len(r), r.path)
|
|
252
237
|
|
|
253
238
|
|
|
254
239
|
def test_labels_and_crops():
|
|
@@ -170,7 +170,7 @@ class BaseDataset(Dataset):
|
|
|
170
170
|
if self.augment:
|
|
171
171
|
self.ims[i], self.im_hw0[i], self.im_hw[i] = im, (h0, w0), im.shape[:2] # im, hw_original, hw_resized
|
|
172
172
|
self.buffer.append(i)
|
|
173
|
-
if len(self.buffer) >= self.max_buffer_length:
|
|
173
|
+
if 1 < len(self.buffer) >= self.max_buffer_length: # prevent empty buffer
|
|
174
174
|
j = self.buffer.pop(0)
|
|
175
175
|
if self.cache != "ram":
|
|
176
176
|
self.ims[j], self.im_hw0[j], self.im_hw[j] = None, None, None
|
|
@@ -88,7 +88,7 @@ from ultralytics.utils import (
|
|
|
88
88
|
yaml_save,
|
|
89
89
|
)
|
|
90
90
|
from ultralytics.utils.checks import check_imgsz, check_is_path_safe, check_requirements, check_version
|
|
91
|
-
from ultralytics.utils.downloads import attempt_download_asset, get_github_assets
|
|
91
|
+
from ultralytics.utils.downloads import attempt_download_asset, get_github_assets, safe_download
|
|
92
92
|
from ultralytics.utils.files import file_size, spaces_in_path
|
|
93
93
|
from ultralytics.utils.ops import Profile
|
|
94
94
|
from ultralytics.utils.torch_utils import TORCH_1_13, get_latest_opset, select_device, smart_inference_mode
|
|
@@ -200,6 +200,8 @@ class Exporter:
|
|
|
200
200
|
self.args.half = False
|
|
201
201
|
assert not self.args.dynamic, "half=True not compatible with dynamic=True, i.e. use only one."
|
|
202
202
|
self.imgsz = check_imgsz(self.args.imgsz, stride=model.stride, min_dim=2) # check image size
|
|
203
|
+
if self.args.int8 and engine:
|
|
204
|
+
self.args.dynamic = True # enforce dynamic to export TensorRT INT8; ensures ONNX is dynamic
|
|
203
205
|
if self.args.optimize:
|
|
204
206
|
assert not ncnn, "optimize=True not compatible with format='ncnn', i.e. use optimize=False"
|
|
205
207
|
assert self.device.type == "cpu", "optimize=True not compatible with cuda devices, i.e. use device='cpu'"
|
|
@@ -349,12 +351,12 @@ class Exporter:
|
|
|
349
351
|
task=self.model.task,
|
|
350
352
|
imgsz=self.imgsz[0],
|
|
351
353
|
augment=False,
|
|
352
|
-
batch_size=self.args.batch,
|
|
354
|
+
batch_size=self.args.batch * 2, # NOTE TensorRT INT8 calibration should use 2x batch size
|
|
353
355
|
)
|
|
354
356
|
n = len(dataset)
|
|
355
357
|
if n < 300:
|
|
356
358
|
LOGGER.warning(f"{prefix} WARNING ⚠️ >300 images recommended for INT8 calibration, found {n} images.")
|
|
357
|
-
return build_dataloader(dataset, batch=self.args.batch, workers=0) # required for batch loading
|
|
359
|
+
return build_dataloader(dataset, batch=self.args.batch * 2, workers=0) # required for batch loading
|
|
358
360
|
|
|
359
361
|
@try_export
|
|
360
362
|
def export_torchscript(self, prefix=colorstr("TorchScript:")):
|
|
@@ -533,7 +535,7 @@ class Exporter:
|
|
|
533
535
|
f_ts = self.file.with_suffix(".torchscript")
|
|
534
536
|
|
|
535
537
|
name = Path("pnnx.exe" if WINDOWS else "pnnx") # PNNX filename
|
|
536
|
-
pnnx = name if name.is_file() else ROOT / name
|
|
538
|
+
pnnx = name if name.is_file() else (ROOT / name)
|
|
537
539
|
if not pnnx.is_file():
|
|
538
540
|
LOGGER.warning(
|
|
539
541
|
f"{prefix} WARNING ⚠️ PNNX not found. Attempting to download binary file from "
|
|
@@ -542,19 +544,19 @@ class Exporter:
|
|
|
542
544
|
)
|
|
543
545
|
system = "macos" if MACOS else "windows" if WINDOWS else "linux-aarch64" if ARM64 else "linux"
|
|
544
546
|
try:
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
assert
|
|
547
|
+
release, assets = get_github_assets(repo="pnnx/pnnx")
|
|
548
|
+
asset = [x for x in assets if f"{system}.zip" in x][0]
|
|
549
|
+
assert isinstance(asset, str), "Unable to retrieve PNNX repo assets" # i.e. pnnx-20240410-macos.zip
|
|
550
|
+
LOGGER.info(f"{prefix} successfully found latest PNNX asset file {asset}")
|
|
548
551
|
except Exception as e:
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
552
|
+
release = "20240410"
|
|
553
|
+
asset = f"pnnx-{release}-{system}.zip"
|
|
554
|
+
LOGGER.warning(f"{prefix} WARNING ⚠️ PNNX GitHub assets not found: {e}, using default {asset}")
|
|
555
|
+
unzip_dir = safe_download(f"https://github.com/pnnx/pnnx/releases/download/{release}/{asset}", delete=True)
|
|
556
|
+
if check_is_path_safe(Path.cwd(), unzip_dir): # avoid path traversal security vulnerability
|
|
554
557
|
(unzip_dir / name).rename(pnnx) # move binary to ROOT
|
|
555
|
-
shutil.rmtree(unzip_dir) # delete unzip dir
|
|
556
|
-
Path(asset).unlink() # delete zip
|
|
557
558
|
pnnx.chmod(0o777) # set read, write, and execute permissions for everyone
|
|
559
|
+
shutil.rmtree(unzip_dir) # delete unzip dir
|
|
558
560
|
|
|
559
561
|
ncnn_args = [
|
|
560
562
|
f'ncnnparam={f / "model.ncnn.param"}',
|
|
@@ -599,6 +601,7 @@ class Exporter:
|
|
|
599
601
|
|
|
600
602
|
LOGGER.info(f"\n{prefix} starting export with coremltools {ct.__version__}...")
|
|
601
603
|
assert not WINDOWS, "CoreML export is not supported on Windows, please run on macOS or Linux."
|
|
604
|
+
assert self.args.batch == 1, "CoreML batch sizes > 1 are not supported. Please retry at 'batch=1'."
|
|
602
605
|
f = self.file.with_suffix(".mlmodel" if mlmodel else ".mlpackage")
|
|
603
606
|
if f.is_dir():
|
|
604
607
|
shutil.rmtree(f)
|
|
@@ -678,6 +681,7 @@ class Exporter:
|
|
|
678
681
|
import tensorrt as trt # noqa
|
|
679
682
|
check_version(trt.__version__, "7.0.0", hard=True) # require tensorrt>=7.0.0
|
|
680
683
|
|
|
684
|
+
# Setup and checks
|
|
681
685
|
LOGGER.info(f"\n{prefix} starting export with TensorRT {trt.__version__}...")
|
|
682
686
|
is_trt10 = int(trt.__version__.split(".")[0]) >= 10 # is TensorRT >= 10
|
|
683
687
|
assert Path(f_onnx).exists(), f"failed to export ONNX file: {f_onnx}"
|
|
@@ -686,6 +690,7 @@ class Exporter:
|
|
|
686
690
|
if self.args.verbose:
|
|
687
691
|
logger.min_severity = trt.Logger.Severity.VERBOSE
|
|
688
692
|
|
|
693
|
+
# Engine builder
|
|
689
694
|
builder = trt.Builder(logger)
|
|
690
695
|
config = builder.create_builder_config()
|
|
691
696
|
workspace = int(self.args.workspace * (1 << 30))
|
|
@@ -695,10 +700,14 @@ class Exporter:
|
|
|
695
700
|
config.max_workspace_size = workspace
|
|
696
701
|
flag = 1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)
|
|
697
702
|
network = builder.create_network(flag)
|
|
703
|
+
half = builder.platform_has_fast_fp16 and self.args.half
|
|
704
|
+
int8 = builder.platform_has_fast_int8 and self.args.int8
|
|
705
|
+
# Read ONNX file
|
|
698
706
|
parser = trt.OnnxParser(network, logger)
|
|
699
707
|
if not parser.parse_from_file(f_onnx):
|
|
700
708
|
raise RuntimeError(f"failed to load ONNX file: {f_onnx}")
|
|
701
709
|
|
|
710
|
+
# Network inputs
|
|
702
711
|
inputs = [network.get_input(i) for i in range(network.num_inputs)]
|
|
703
712
|
outputs = [network.get_output(i) for i in range(network.num_outputs)]
|
|
704
713
|
for inp in inputs:
|
|
@@ -712,15 +721,67 @@ class Exporter:
|
|
|
712
721
|
LOGGER.warning(f"{prefix} WARNING ⚠️ 'dynamic=True' model requires max batch size, i.e. 'batch=16'")
|
|
713
722
|
profile = builder.create_optimization_profile()
|
|
714
723
|
min_shape = (1, shape[1], 32, 32) # minimum input shape
|
|
715
|
-
opt_shape = (max(1, shape[0] // 2), *shape[1:]) # optimal input shape
|
|
716
724
|
max_shape = (*shape[:2], *(max(1, self.args.workspace) * d for d in shape[2:])) # max input shape
|
|
717
725
|
for inp in inputs:
|
|
718
|
-
profile.set_shape(inp.name, min_shape,
|
|
726
|
+
profile.set_shape(inp.name, min=min_shape, opt=shape, max=max_shape)
|
|
719
727
|
config.add_optimization_profile(profile)
|
|
720
728
|
|
|
721
|
-
half
|
|
722
|
-
|
|
723
|
-
|
|
729
|
+
LOGGER.info(f"{prefix} building {'INT8' if int8 else 'FP' + ('16' if half else '32')} engine as {f}")
|
|
730
|
+
if int8:
|
|
731
|
+
config.set_flag(trt.BuilderFlag.INT8)
|
|
732
|
+
config.set_calibration_profile(profile)
|
|
733
|
+
config.profiling_verbosity = trt.ProfilingVerbosity.DETAILED
|
|
734
|
+
|
|
735
|
+
class EngineCalibrator(trt.IInt8Calibrator):
|
|
736
|
+
def __init__(
|
|
737
|
+
self,
|
|
738
|
+
dataset, # ultralytics.data.build.InfiniteDataLoader
|
|
739
|
+
batch: int,
|
|
740
|
+
cache: str = "",
|
|
741
|
+
) -> None:
|
|
742
|
+
trt.IInt8Calibrator.__init__(self)
|
|
743
|
+
self.dataset = dataset
|
|
744
|
+
self.data_iter = iter(dataset)
|
|
745
|
+
self.algo = trt.CalibrationAlgoType.ENTROPY_CALIBRATION_2
|
|
746
|
+
self.batch = batch
|
|
747
|
+
self.cache = Path(cache)
|
|
748
|
+
|
|
749
|
+
def get_algorithm(self) -> trt.CalibrationAlgoType:
|
|
750
|
+
"""Get the calibration algorithm to use."""
|
|
751
|
+
return self.algo
|
|
752
|
+
|
|
753
|
+
def get_batch_size(self) -> int:
|
|
754
|
+
"""Get the batch size to use for calibration."""
|
|
755
|
+
return self.batch or 1
|
|
756
|
+
|
|
757
|
+
def get_batch(self, names) -> list:
|
|
758
|
+
"""Get the next batch to use for calibration, as a list of device memory pointers."""
|
|
759
|
+
try:
|
|
760
|
+
im0s = next(self.data_iter)["img"] / 255.0
|
|
761
|
+
im0s = im0s.to("cuda") if im0s.device.type == "cpu" else im0s
|
|
762
|
+
return [int(im0s.data_ptr())]
|
|
763
|
+
except StopIteration:
|
|
764
|
+
# Return [] or None, signal to TensorRT there is no calibration data remaining
|
|
765
|
+
return None
|
|
766
|
+
|
|
767
|
+
def read_calibration_cache(self) -> bytes:
|
|
768
|
+
"""Use existing cache instead of calibrating again, otherwise, implicitly return None."""
|
|
769
|
+
if self.cache.exists() and self.cache.suffix == ".cache":
|
|
770
|
+
return self.cache.read_bytes()
|
|
771
|
+
|
|
772
|
+
def write_calibration_cache(self, cache) -> None:
|
|
773
|
+
"""Write calibration cache to disk."""
|
|
774
|
+
_ = self.cache.write_bytes(cache)
|
|
775
|
+
|
|
776
|
+
# Load dataset w/ builder (for batching) and calibrate
|
|
777
|
+
dataset = self.get_int8_calibration_dataloader(prefix)
|
|
778
|
+
config.int8_calibrator = EngineCalibrator(
|
|
779
|
+
dataset=dataset,
|
|
780
|
+
batch=2 * self.args.batch,
|
|
781
|
+
cache=self.file.with_suffix(".cache"),
|
|
782
|
+
)
|
|
783
|
+
|
|
784
|
+
elif half:
|
|
724
785
|
config.set_flag(trt.BuilderFlag.FP16)
|
|
725
786
|
|
|
726
787
|
# Free CUDA memory
|
|
@@ -387,26 +387,32 @@ class Results(SimpleClass):
|
|
|
387
387
|
|
|
388
388
|
def summary(self, normalize=False, decimals=5):
|
|
389
389
|
"""Convert the results to a summarized format."""
|
|
390
|
-
if self.probs is not None:
|
|
391
|
-
LOGGER.warning("Warning: Classify results do not support the `summary()` method yet.")
|
|
392
|
-
return
|
|
393
|
-
|
|
394
390
|
# Create list of detection dictionaries
|
|
395
391
|
results = []
|
|
396
|
-
|
|
392
|
+
if self.probs is not None:
|
|
393
|
+
class_id = self.probs.top1
|
|
394
|
+
results.append(
|
|
395
|
+
{
|
|
396
|
+
"name": self.names[class_id],
|
|
397
|
+
"class": class_id,
|
|
398
|
+
"confidence": round(self.probs.top1conf.item(), decimals),
|
|
399
|
+
}
|
|
400
|
+
)
|
|
401
|
+
return results
|
|
402
|
+
|
|
403
|
+
data = self.boxes or self.obb
|
|
404
|
+
is_obb = self.obb is not None
|
|
397
405
|
h, w = self.orig_shape if normalize else (1, 1)
|
|
398
406
|
for i, row in enumerate(data): # xyxy, track_id if tracking, conf, class_id
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
"
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
if self.boxes.is_track:
|
|
409
|
-
result["track_id"] = int(row[-3]) # track ID
|
|
407
|
+
class_id, conf = int(row.cls), round(row.conf.item(), decimals)
|
|
408
|
+
box = (row.xyxyxyxy if is_obb else row.xyxy).squeeze().reshape(-1, 2).tolist()
|
|
409
|
+
xy = {}
|
|
410
|
+
for i, b in enumerate(box):
|
|
411
|
+
xy[f"x{i + 1}"] = round(b[0] / w, decimals)
|
|
412
|
+
xy[f"y{i + 1}"] = round(b[1] / h, decimals)
|
|
413
|
+
result = {"name": self.names[class_id], "class": class_id, "confidence": conf, "box": xy}
|
|
414
|
+
if data.is_track:
|
|
415
|
+
result["track_id"] = int(row.id.item()) # track ID
|
|
410
416
|
if self.masks:
|
|
411
417
|
result["segments"] = {
|
|
412
418
|
"x": (self.masks.xy[i][:, 0] / w).round(decimals).tolist(),
|
|
@@ -15,7 +15,7 @@ class YOLO(Model):
|
|
|
15
15
|
"""Initialize YOLO model, switching to YOLOWorld if model filename contains '-world'."""
|
|
16
16
|
path = Path(model)
|
|
17
17
|
if "-world" in path.stem and path.suffix in {".pt", ".yaml", ".yml"}: # if YOLOWorld PyTorch model
|
|
18
|
-
new_instance = YOLOWorld(path)
|
|
18
|
+
new_instance = YOLOWorld(path, verbose=verbose)
|
|
19
19
|
self.__class__ = type(new_instance)
|
|
20
20
|
self.__dict__ = new_instance.__dict__
|
|
21
21
|
else:
|
|
@@ -62,14 +62,14 @@ class YOLO(Model):
|
|
|
62
62
|
class YOLOWorld(Model):
|
|
63
63
|
"""YOLO-World object detection model."""
|
|
64
64
|
|
|
65
|
-
def __init__(self, model="yolov8s-world.pt") -> None:
|
|
65
|
+
def __init__(self, model="yolov8s-world.pt", verbose=False) -> None:
|
|
66
66
|
"""
|
|
67
67
|
Initializes the YOLOv8-World model with the given pre-trained model file. Supports *.pt and *.yaml formats.
|
|
68
68
|
|
|
69
69
|
Args:
|
|
70
70
|
model (str | Path): Path to the pre-trained model. Defaults to 'yolov8s-world.pt'.
|
|
71
71
|
"""
|
|
72
|
-
super().__init__(model=model, task="detect")
|
|
72
|
+
super().__init__(model=model, task="detect", verbose=verbose)
|
|
73
73
|
|
|
74
74
|
# Assign default COCO class names when there are no custom names
|
|
75
75
|
if not hasattr(self.model, "names"):
|
|
@@ -528,7 +528,7 @@ def check_is_path_safe(basedir, path):
|
|
|
528
528
|
base_dir_resolved = Path(basedir).resolve()
|
|
529
529
|
path_resolved = Path(path).resolve()
|
|
530
530
|
|
|
531
|
-
return path_resolved.
|
|
531
|
+
return path_resolved.exists() and path_resolved.parts[: len(base_dir_resolved.parts)] == base_dir_resolved.parts
|
|
532
532
|
|
|
533
533
|
|
|
534
534
|
def check_imshow(warn=False):
|
|
@@ -418,7 +418,7 @@ def attempt_download_asset(file, repo="ultralytics/assets", release="v8.2.0", **
|
|
|
418
418
|
|
|
419
419
|
Example:
|
|
420
420
|
```python
|
|
421
|
-
file_path = attempt_download_asset('
|
|
421
|
+
file_path = attempt_download_asset('yolov8n.pt', repo='ultralytics/assets', release='latest')
|
|
422
422
|
```
|
|
423
423
|
"""
|
|
424
424
|
from ultralytics.utils import SETTINGS # scoped for circular import
|