ultralytics 8.0.194__tar.gz → 8.0.196__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.0.194/ultralytics.egg-info → ultralytics-8.0.196}/PKG-INFO +1 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/setup.cfg +9 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/setup.py +7 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/tests/conftest.py +6 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/tests/test_cli.py +10 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/tests/test_cuda.py +10 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/tests/test_engine.py +5 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/tests/test_python.py +117 -26
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/__init__.py +1 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/__init__.py +5 -6
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/augment.py +234 -29
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/base.py +2 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/build.py +9 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/converter.py +5 -2
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/dataset.py +16 -2
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/loaders.py +111 -7
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/utils.py +3 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/exporter.py +1 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/model.py +16 -9
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/predictor.py +10 -6
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/results.py +18 -8
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/trainer.py +19 -31
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/tuner.py +20 -20
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/validator.py +3 -4
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/hub/__init__.py +2 -2
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/hub/auth.py +18 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/hub/session.py +1 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/hub/utils.py +1 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/model.py +2 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/predict.py +10 -7
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/prompt.py +15 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/nas/model.py +3 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/rtdetr/model.py +4 -6
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/rtdetr/predict.py +2 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/rtdetr/train.py +2 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/rtdetr/val.py +1 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/amg.py +12 -6
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/model.py +5 -6
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/decoders.py +5 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/encoders.py +15 -12
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/tiny_encoder.py +38 -2
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/transformer.py +2 -4
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/predict.py +8 -4
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/utils/loss.py +35 -8
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/utils/ops.py +14 -18
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/classify/predict.py +1 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/classify/train.py +4 -2
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/classify/val.py +1 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/detect/train.py +4 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/model.py +2 -4
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/pose/predict.py +1 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/segment/predict.py +2 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/segment/val.py +1 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/autobackend.py +54 -43
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/__init__.py +13 -9
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/block.py +11 -5
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/conv.py +16 -7
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/head.py +6 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/transformer.py +47 -15
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/utils.py +6 -4
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/tasks.py +61 -21
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/bot_sort.py +53 -6
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/byte_tracker.py +71 -15
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/track.py +0 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/utils/gmc.py +23 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/utils/kalman_filter.py +6 -6
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/__init__.py +32 -19
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/autobatch.py +1 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/benchmarks.py +14 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/base.py +1 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/comet.py +11 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/dvc.py +9 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/neptune.py +5 -6
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/wb.py +1 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/checks.py +13 -9
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/dist.py +2 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/downloads.py +7 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/files.py +3 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/instance.py +12 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/loss.py +97 -22
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/metrics.py +35 -34
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/ops.py +10 -9
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/patches.py +9 -7
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/plotting.py +4 -3
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/torch_utils.py +8 -6
- ultralytics-8.0.196/ultralytics/utils/triton.py +87 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196/ultralytics.egg-info}/PKG-INFO +1 -1
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics.egg-info/SOURCES.txt +1 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/CONTRIBUTING.md +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/LICENSE +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/MANIFEST.in +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/README.md +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/README.zh-CN.md +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/requirements.txt +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/assets/bus.jpg +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/assets/zidane.jpg +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/Argoverse.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/DOTAv2.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/GlobalWheat2020.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/ImageNet.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/Objects365.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/SKU-110K.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/VOC.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/VisDrone.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco-pose.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco128-seg.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco128.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco8-pose.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco8-seg.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco8.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/open-images-v7.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/tiger-pose.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/xView.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/default.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v3/yolov3-spp.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v3/yolov3-tiny.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v3/yolov3.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v5/yolov5-p6.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v5/yolov5.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v6/yolov6.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-cls.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-p2.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-p6.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-pose.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-seg.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/trackers/botsort.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/trackers/bytetrack.yaml +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/annotator.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/utils.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/val.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/nas/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/nas/predict.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/nas/val.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/rtdetr/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/build.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/sam.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/utils/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/classify/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/detect/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/detect/predict.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/detect/val.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/pose/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/pose/train.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/pose/val.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/segment/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/segment/train.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/basetrack.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/utils/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/utils/matching.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/__init__.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/clearml.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/hub.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/mlflow.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/raytune.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/tensorboard.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/errors.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/tal.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/tuner.py +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics.egg-info/dependency_links.txt +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics.egg-info/entry_points.txt +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics.egg-info/requires.txt +0 -0
- {ultralytics-8.0.194 → ultralytics-8.0.196}/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.0.
|
|
3
|
+
Version: 8.0.196
|
|
4
4
|
Summary: Ultralytics YOLOv8 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
|
|
5
5
|
Home-page: https://github.com/ultralytics/ultralytics
|
|
6
6
|
Author: Ultralytics
|
|
@@ -41,6 +41,15 @@ SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET = True
|
|
|
41
41
|
SPLIT_BEFORE_CLOSING_BRACKET = False
|
|
42
42
|
SPLIT_BEFORE_FIRST_ARGUMENT = False
|
|
43
43
|
|
|
44
|
+
[docformatter]
|
|
45
|
+
wrap-summaries = 120
|
|
46
|
+
wrap-descriptions = 120
|
|
47
|
+
in-place = true
|
|
48
|
+
make-summary-multi-line = false
|
|
49
|
+
pre-summary-newline = true
|
|
50
|
+
force-wrap = false
|
|
51
|
+
close-quotes-on-newline = true
|
|
52
|
+
|
|
44
53
|
[egg_info]
|
|
45
54
|
tag_build =
|
|
46
55
|
tag_date = 0
|
|
@@ -12,6 +12,12 @@ README = (PARENT / 'README.md').read_text(encoding='utf-8')
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def get_version():
|
|
15
|
+
"""
|
|
16
|
+
Retrieve the version number from the 'ultralytics/__init__.py' file.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
(str): The version number extracted from the '__version__' attribute in the 'ultralytics/__init__.py' file.
|
|
20
|
+
"""
|
|
15
21
|
file = PARENT / 'ultralytics/__init__.py'
|
|
16
22
|
return re.search(r'^__version__ = [\'"]([^\'"]*)[\'"]', file.read_text(encoding='utf-8'), re.M)[1]
|
|
17
23
|
|
|
@@ -24,7 +30,7 @@ def parse_requirements(file_path: Path):
|
|
|
24
30
|
file_path (str | Path): Path to the requirements.txt file.
|
|
25
31
|
|
|
26
32
|
Returns:
|
|
27
|
-
List[str]: List of parsed requirements.
|
|
33
|
+
(List[str]): List of parsed requirements.
|
|
28
34
|
"""
|
|
29
35
|
|
|
30
36
|
requirements = []
|
|
@@ -9,7 +9,8 @@ TMP = Path(__file__).resolve().parent / 'tmp' # temp directory for test files
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def pytest_addoption(parser):
|
|
12
|
-
"""
|
|
12
|
+
"""
|
|
13
|
+
Add custom command-line options to pytest.
|
|
13
14
|
|
|
14
15
|
Args:
|
|
15
16
|
parser (pytest.config.Parser): The pytest parser object.
|
|
@@ -18,7 +19,8 @@ def pytest_addoption(parser):
|
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
def pytest_configure(config):
|
|
21
|
-
"""
|
|
22
|
+
"""
|
|
23
|
+
Register custom markers to avoid pytest warnings.
|
|
22
24
|
|
|
23
25
|
Args:
|
|
24
26
|
config (pytest.config.Config): The pytest config object.
|
|
@@ -27,7 +29,8 @@ def pytest_configure(config):
|
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
def pytest_runtest_setup(item):
|
|
30
|
-
"""
|
|
32
|
+
"""
|
|
33
|
+
Setup hook to skip tests marked as slow if the --slow option is not provided.
|
|
31
34
|
|
|
32
35
|
Args:
|
|
33
36
|
item (pytest.Item): The test item object.
|
|
@@ -22,11 +22,12 @@ EXPORT_ARGS = [
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def run(cmd):
|
|
25
|
-
|
|
25
|
+
"""Execute a shell command using subprocess."""
|
|
26
26
|
subprocess.run(cmd.split(), check=True)
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def test_special_modes():
|
|
30
|
+
"""Test various special command modes of YOLO."""
|
|
30
31
|
run('yolo help')
|
|
31
32
|
run('yolo checks')
|
|
32
33
|
run('yolo version')
|
|
@@ -36,31 +37,37 @@ def test_special_modes():
|
|
|
36
37
|
|
|
37
38
|
@pytest.mark.parametrize('task,model,data', TASK_ARGS)
|
|
38
39
|
def test_train(task, model, data):
|
|
40
|
+
"""Test YOLO training for a given task, model, and data."""
|
|
39
41
|
run(f'yolo train {task} model={model}.yaml data={data} imgsz=32 epochs=1 cache=disk')
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
@pytest.mark.parametrize('task,model,data', TASK_ARGS)
|
|
43
45
|
def test_val(task, model, data):
|
|
46
|
+
"""Test YOLO validation for a given task, model, and data."""
|
|
44
47
|
run(f'yolo val {task} model={WEIGHTS_DIR / model}.pt data={data} imgsz=32 save_txt save_json')
|
|
45
48
|
|
|
46
49
|
|
|
47
50
|
@pytest.mark.parametrize('task,model,data', TASK_ARGS)
|
|
48
51
|
def test_predict(task, model, data):
|
|
52
|
+
"""Test YOLO prediction on sample assets for a given task and model."""
|
|
49
53
|
run(f'yolo predict model={WEIGHTS_DIR / model}.pt source={ASSETS} imgsz=32 save save_crop save_txt')
|
|
50
54
|
|
|
51
55
|
|
|
52
56
|
@pytest.mark.parametrize('model,format', EXPORT_ARGS)
|
|
53
57
|
def test_export(model, format):
|
|
58
|
+
"""Test exporting a YOLO model to different formats."""
|
|
54
59
|
run(f'yolo export model={WEIGHTS_DIR / model}.pt format={format} imgsz=32')
|
|
55
60
|
|
|
56
61
|
|
|
57
62
|
def test_rtdetr(task='detect', model='yolov8n-rtdetr.yaml', data='coco8.yaml'):
|
|
63
|
+
"""Test the RTDETR functionality with the Ultralytics framework."""
|
|
58
64
|
# Warning: MUST use imgsz=640
|
|
59
65
|
run(f'yolo train {task} model={model} data={data} --imgsz= 640 epochs =1, cache = disk') # add coma, spaces to args
|
|
60
66
|
run(f"yolo predict {task} model={model} source={ASSETS / 'bus.jpg'} imgsz=640 save save_crop save_txt")
|
|
61
67
|
|
|
62
68
|
|
|
63
69
|
def test_fastsam(task='segment', model=WEIGHTS_DIR / 'FastSAM-s.pt', data='coco8-seg.yaml'):
|
|
70
|
+
"""Test FastSAM segmentation functionality within Ultralytics."""
|
|
64
71
|
source = ASSETS / 'bus.jpg'
|
|
65
72
|
|
|
66
73
|
run(f'yolo segment val {task} model={model} data={data} imgsz=32')
|
|
@@ -97,6 +104,7 @@ def test_fastsam(task='segment', model=WEIGHTS_DIR / 'FastSAM-s.pt', data='coco8
|
|
|
97
104
|
|
|
98
105
|
|
|
99
106
|
def test_mobilesam():
|
|
107
|
+
"""Test MobileSAM segmentation functionality using Ultralytics."""
|
|
100
108
|
from ultralytics import SAM
|
|
101
109
|
|
|
102
110
|
# Load the model
|
|
@@ -121,5 +129,6 @@ def test_mobilesam():
|
|
|
121
129
|
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason='CUDA is not available')
|
|
122
130
|
@pytest.mark.skipif(CUDA_DEVICE_COUNT < 2, reason='DDP is not available')
|
|
123
131
|
def test_train_gpu(task, model, data):
|
|
132
|
+
"""Test YOLO training on GPU(s) for various tasks and models."""
|
|
124
133
|
run(f'yolo train {task} model={model}.yaml data={data} imgsz=32 epochs=1 device=0') # single GPU
|
|
125
134
|
run(f'yolo train {task} model={model}.pt data={data} imgsz=32 epochs=1 device=0,1') # multi GPU
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
|
2
|
+
|
|
2
3
|
import contextlib
|
|
3
4
|
|
|
4
5
|
import pytest
|
|
@@ -17,18 +18,21 @@ BUS = ASSETS / 'bus.jpg'
|
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
def test_checks():
|
|
21
|
+
"""Validate CUDA settings against torch CUDA functions."""
|
|
20
22
|
assert torch.cuda.is_available() == CUDA_IS_AVAILABLE
|
|
21
23
|
assert torch.cuda.device_count() == CUDA_DEVICE_COUNT
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason='CUDA is not available')
|
|
25
27
|
def test_train():
|
|
28
|
+
"""Test model training on a minimal dataset."""
|
|
26
29
|
device = 0 if CUDA_DEVICE_COUNT == 1 else [0, 1]
|
|
27
30
|
YOLO(MODEL).train(data=DATA, imgsz=64, epochs=1, device=device) # requires imgsz>=64
|
|
28
31
|
|
|
29
32
|
|
|
30
33
|
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason='CUDA is not available')
|
|
31
34
|
def test_predict_multiple_devices():
|
|
35
|
+
"""Validate model prediction on multiple devices."""
|
|
32
36
|
model = YOLO('yolov8n.pt')
|
|
33
37
|
model = model.cpu()
|
|
34
38
|
assert str(model.device) == 'cpu'
|
|
@@ -53,6 +57,7 @@ def test_predict_multiple_devices():
|
|
|
53
57
|
|
|
54
58
|
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason='CUDA is not available')
|
|
55
59
|
def test_autobatch():
|
|
60
|
+
"""Check batch size for YOLO model using autobatch."""
|
|
56
61
|
from ultralytics.utils.autobatch import check_train_batch_size
|
|
57
62
|
|
|
58
63
|
check_train_batch_size(YOLO(MODEL).model.cuda(), imgsz=128, amp=True)
|
|
@@ -60,6 +65,7 @@ def test_autobatch():
|
|
|
60
65
|
|
|
61
66
|
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason='CUDA is not available')
|
|
62
67
|
def test_utils_benchmarks():
|
|
68
|
+
"""Profile YOLO models for performance benchmarks."""
|
|
63
69
|
from ultralytics.utils.benchmarks import ProfileModels
|
|
64
70
|
|
|
65
71
|
# Pre-export a dynamic engine model to use dynamic inference
|
|
@@ -69,6 +75,7 @@ def test_utils_benchmarks():
|
|
|
69
75
|
|
|
70
76
|
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason='CUDA is not available')
|
|
71
77
|
def test_predict_sam():
|
|
78
|
+
"""Test SAM model prediction with various prompts."""
|
|
72
79
|
from ultralytics import SAM
|
|
73
80
|
from ultralytics.models.sam import Predictor as SAMPredictor
|
|
74
81
|
|
|
@@ -102,6 +109,7 @@ def test_predict_sam():
|
|
|
102
109
|
|
|
103
110
|
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason='CUDA is not available')
|
|
104
111
|
def test_model_ray_tune():
|
|
112
|
+
"""Tune YOLO model with Ray optimization library."""
|
|
105
113
|
with contextlib.suppress(RuntimeError): # RuntimeError may be caused by out-of-memory
|
|
106
114
|
YOLO('yolov8n-cls.yaml').tune(use_ray=True,
|
|
107
115
|
data='imagenet10',
|
|
@@ -115,12 +123,14 @@ def test_model_ray_tune():
|
|
|
115
123
|
|
|
116
124
|
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason='CUDA is not available')
|
|
117
125
|
def test_model_tune():
|
|
126
|
+
"""Tune YOLO model for performance."""
|
|
118
127
|
YOLO('yolov8n-pose.pt').tune(data='coco8-pose.yaml', plots=False, imgsz=32, epochs=1, iterations=2, device='cpu')
|
|
119
128
|
YOLO('yolov8n-cls.pt').tune(data='imagenet10', plots=False, imgsz=32, epochs=1, iterations=2, device='cpu')
|
|
120
129
|
|
|
121
130
|
|
|
122
131
|
@pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason='CUDA is not available')
|
|
123
132
|
def test_pycocotools():
|
|
133
|
+
"""Validate model predictions using pycocotools."""
|
|
124
134
|
from ultralytics.models.yolo.detect import DetectionValidator
|
|
125
135
|
from ultralytics.models.yolo.pose import PoseValidator
|
|
126
136
|
from ultralytics.models.yolo.segment import SegmentationValidator
|
|
@@ -14,10 +14,12 @@ MODEL = WEIGHTS_DIR / 'yolov8n'
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def test_func(*args): # noqa
|
|
17
|
+
"""Test function callback."""
|
|
17
18
|
print('callback test passed')
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
def test_export():
|
|
22
|
+
"""Test model exporting functionality."""
|
|
21
23
|
exporter = Exporter()
|
|
22
24
|
exporter.add_callback('on_export_start', test_func)
|
|
23
25
|
assert test_func in exporter.callbacks['on_export_start'], 'callback test failed'
|
|
@@ -26,6 +28,7 @@ def test_export():
|
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
def test_detect():
|
|
31
|
+
"""Test object detection functionality."""
|
|
29
32
|
overrides = {'data': 'coco8.yaml', 'model': CFG_DET, 'imgsz': 32, 'epochs': 1, 'save': False}
|
|
30
33
|
CFG.data = 'coco8.yaml'
|
|
31
34
|
CFG.imgsz = 32
|
|
@@ -61,6 +64,7 @@ def test_detect():
|
|
|
61
64
|
|
|
62
65
|
|
|
63
66
|
def test_segment():
|
|
67
|
+
"""Test image segmentation functionality."""
|
|
64
68
|
overrides = {'data': 'coco8-seg.yaml', 'model': CFG_SEG, 'imgsz': 32, 'epochs': 1, 'save': False}
|
|
65
69
|
CFG.data = 'coco8-seg.yaml'
|
|
66
70
|
CFG.imgsz = 32
|
|
@@ -98,6 +102,7 @@ def test_segment():
|
|
|
98
102
|
|
|
99
103
|
|
|
100
104
|
def test_classify():
|
|
105
|
+
"""Test image classification functionality."""
|
|
101
106
|
overrides = {'data': 'imagenet10', 'model': CFG_CLS, 'imgsz': 32, 'epochs': 1, 'save': False}
|
|
102
107
|
CFG.data = 'imagenet10'
|
|
103
108
|
CFG.imgsz = 32
|
|
@@ -15,7 +15,7 @@ from ultralytics import RTDETR, YOLO
|
|
|
15
15
|
from ultralytics.cfg import TASK2DATA
|
|
16
16
|
from ultralytics.data.build import load_inference_source
|
|
17
17
|
from ultralytics.utils import (ASSETS, DEFAULT_CFG, DEFAULT_CFG_PATH, LINUX, MACOS, ONLINE, ROOT, WEIGHTS_DIR, WINDOWS,
|
|
18
|
-
is_dir_writeable)
|
|
18
|
+
checks, is_dir_writeable)
|
|
19
19
|
from ultralytics.utils.downloads import download
|
|
20
20
|
from ultralytics.utils.torch_utils import TORCH_1_9
|
|
21
21
|
|
|
@@ -27,11 +27,13 @@ IS_TMP_WRITEABLE = is_dir_writeable(TMP)
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def test_model_forward():
|
|
30
|
+
"""Test the forward pass of the YOLO model."""
|
|
30
31
|
model = YOLO(CFG)
|
|
31
32
|
model(source=None, imgsz=32, augment=True) # also test no source and augment
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
def test_model_methods():
|
|
36
|
+
"""Test various methods and properties of the YOLO model."""
|
|
35
37
|
model = YOLO(MODEL)
|
|
36
38
|
|
|
37
39
|
# Model methods
|
|
@@ -51,7 +53,7 @@ def test_model_methods():
|
|
|
51
53
|
|
|
52
54
|
|
|
53
55
|
def test_model_profile():
|
|
54
|
-
|
|
56
|
+
"""Test profiling of the YOLO model with 'profile=True' argument."""
|
|
55
57
|
from ultralytics.nn.tasks import DetectionModel
|
|
56
58
|
|
|
57
59
|
model = DetectionModel() # build model
|
|
@@ -61,7 +63,7 @@ def test_model_profile():
|
|
|
61
63
|
|
|
62
64
|
@pytest.mark.skipif(not IS_TMP_WRITEABLE, reason='directory is not writeable')
|
|
63
65
|
def test_predict_txt():
|
|
64
|
-
|
|
66
|
+
"""Test YOLO predictions with sources (file, dir, glob, recursive glob) specified in a text file."""
|
|
65
67
|
txt_file = TMP / 'sources.txt'
|
|
66
68
|
with open(txt_file, 'w') as f:
|
|
67
69
|
for x in [ASSETS / 'bus.jpg', ASSETS, ASSETS / '*', ASSETS / '**/*.jpg']:
|
|
@@ -70,6 +72,7 @@ def test_predict_txt():
|
|
|
70
72
|
|
|
71
73
|
|
|
72
74
|
def test_predict_img():
|
|
75
|
+
"""Test YOLO prediction on various types of image sources."""
|
|
73
76
|
model = YOLO(MODEL)
|
|
74
77
|
seg_model = YOLO(WEIGHTS_DIR / 'yolov8n-seg.pt')
|
|
75
78
|
cls_model = YOLO(WEIGHTS_DIR / 'yolov8n-cls.pt')
|
|
@@ -105,7 +108,7 @@ def test_predict_img():
|
|
|
105
108
|
|
|
106
109
|
|
|
107
110
|
def test_predict_grey_and_4ch():
|
|
108
|
-
|
|
111
|
+
"""Test YOLO prediction on SOURCE converted to greyscale and 4-channel images."""
|
|
109
112
|
im = Image.open(SOURCE)
|
|
110
113
|
directory = TMP / 'im4'
|
|
111
114
|
directory.mkdir(parents=True, exist_ok=True)
|
|
@@ -132,8 +135,11 @@ def test_predict_grey_and_4ch():
|
|
|
132
135
|
@pytest.mark.skipif(not ONLINE, reason='environment is offline')
|
|
133
136
|
@pytest.mark.skipif(not IS_TMP_WRITEABLE, reason='directory is not writeable')
|
|
134
137
|
def test_track_stream():
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
"""
|
|
139
|
+
Test YouTube streaming tracking (short 10 frame video) with non-default ByteTrack tracker.
|
|
140
|
+
|
|
141
|
+
Note imgsz=160 required for tracking for higher confidence and better matches
|
|
142
|
+
"""
|
|
137
143
|
import yaml
|
|
138
144
|
|
|
139
145
|
model = YOLO(MODEL)
|
|
@@ -153,37 +159,44 @@ def test_track_stream():
|
|
|
153
159
|
|
|
154
160
|
|
|
155
161
|
def test_val():
|
|
162
|
+
"""Test the validation mode of the YOLO model."""
|
|
156
163
|
YOLO(MODEL).val(data='coco8.yaml', imgsz=32, save_hybrid=True)
|
|
157
164
|
|
|
158
165
|
|
|
159
166
|
def test_train_scratch():
|
|
167
|
+
"""Test training the YOLO model from scratch."""
|
|
160
168
|
model = YOLO(CFG)
|
|
161
169
|
model.train(data='coco8.yaml', epochs=2, imgsz=32, cache='disk', batch=-1, close_mosaic=1, name='model')
|
|
162
170
|
model(SOURCE)
|
|
163
171
|
|
|
164
172
|
|
|
165
173
|
def test_train_pretrained():
|
|
174
|
+
"""Test training the YOLO model from a pre-trained state."""
|
|
166
175
|
model = YOLO(WEIGHTS_DIR / 'yolov8n-seg.pt')
|
|
167
176
|
model.train(data='coco8-seg.yaml', epochs=1, imgsz=32, cache='ram', copy_paste=0.5, mixup=0.5, name=0)
|
|
168
177
|
model(SOURCE)
|
|
169
178
|
|
|
170
179
|
|
|
171
180
|
def test_export_torchscript():
|
|
181
|
+
"""Test exporting the YOLO model to TorchScript format."""
|
|
172
182
|
f = YOLO(MODEL).export(format='torchscript', optimize=False)
|
|
173
183
|
YOLO(f)(SOURCE) # exported model inference
|
|
174
184
|
|
|
175
185
|
|
|
176
186
|
def test_export_onnx():
|
|
187
|
+
"""Test exporting the YOLO model to ONNX format."""
|
|
177
188
|
f = YOLO(MODEL).export(format='onnx', dynamic=True)
|
|
178
189
|
YOLO(f)(SOURCE) # exported model inference
|
|
179
190
|
|
|
180
191
|
|
|
181
192
|
def test_export_openvino():
|
|
193
|
+
"""Test exporting the YOLO model to OpenVINO format."""
|
|
182
194
|
f = YOLO(MODEL).export(format='openvino')
|
|
183
195
|
YOLO(f)(SOURCE) # exported model inference
|
|
184
196
|
|
|
185
197
|
|
|
186
198
|
def test_export_coreml():
|
|
199
|
+
"""Test exporting the YOLO model to CoreML format."""
|
|
187
200
|
if not WINDOWS: # RuntimeError: BlobWriter not loaded with coremltools 7.0 on windows
|
|
188
201
|
if MACOS:
|
|
189
202
|
f = YOLO(MODEL).export(format='coreml')
|
|
@@ -193,7 +206,11 @@ def test_export_coreml():
|
|
|
193
206
|
|
|
194
207
|
|
|
195
208
|
def test_export_tflite(enabled=False):
|
|
196
|
-
|
|
209
|
+
"""
|
|
210
|
+
Test exporting the YOLO model to TFLite format.
|
|
211
|
+
|
|
212
|
+
Note TF suffers from install conflicts on Windows and macOS.
|
|
213
|
+
"""
|
|
197
214
|
if enabled and LINUX:
|
|
198
215
|
model = YOLO(MODEL)
|
|
199
216
|
f = model.export(format='tflite')
|
|
@@ -201,7 +218,11 @@ def test_export_tflite(enabled=False):
|
|
|
201
218
|
|
|
202
219
|
|
|
203
220
|
def test_export_pb(enabled=False):
|
|
204
|
-
|
|
221
|
+
"""
|
|
222
|
+
Test exporting the YOLO model to *.pb format.
|
|
223
|
+
|
|
224
|
+
Note TF suffers from install conflicts on Windows and macOS.
|
|
225
|
+
"""
|
|
205
226
|
if enabled and LINUX:
|
|
206
227
|
model = YOLO(MODEL)
|
|
207
228
|
f = model.export(format='pb')
|
|
@@ -209,18 +230,24 @@ def test_export_pb(enabled=False):
|
|
|
209
230
|
|
|
210
231
|
|
|
211
232
|
def test_export_paddle(enabled=False):
|
|
212
|
-
|
|
233
|
+
"""
|
|
234
|
+
Test exporting the YOLO model to Paddle format.
|
|
235
|
+
|
|
236
|
+
Note Paddle protobuf requirements conflicting with onnx protobuf requirements.
|
|
237
|
+
"""
|
|
213
238
|
if enabled:
|
|
214
239
|
YOLO(MODEL).export(format='paddle')
|
|
215
240
|
|
|
216
241
|
|
|
217
242
|
@pytest.mark.slow
|
|
218
243
|
def test_export_ncnn():
|
|
244
|
+
"""Test exporting the YOLO model to NCNN format."""
|
|
219
245
|
f = YOLO(MODEL).export(format='ncnn')
|
|
220
246
|
YOLO(f)(SOURCE) # exported model inference
|
|
221
247
|
|
|
222
248
|
|
|
223
249
|
def test_all_model_yamls():
|
|
250
|
+
"""Test YOLO model creation for all available YAML configurations."""
|
|
224
251
|
for m in (ROOT / 'cfg' / 'models').rglob('*.yaml'):
|
|
225
252
|
if 'rtdetr' in m.name:
|
|
226
253
|
if TORCH_1_9: # torch<=1.8 issue - TypeError: __init__() got an unexpected keyword argument 'batch_first'
|
|
@@ -230,6 +257,7 @@ def test_all_model_yamls():
|
|
|
230
257
|
|
|
231
258
|
|
|
232
259
|
def test_workflow():
|
|
260
|
+
"""Test the complete workflow including training, validation, prediction, and exporting."""
|
|
233
261
|
model = YOLO(MODEL)
|
|
234
262
|
model.train(data='coco8.yaml', epochs=1, imgsz=32, optimizer='SGD')
|
|
235
263
|
model.val(imgsz=32)
|
|
@@ -238,12 +266,14 @@ def test_workflow():
|
|
|
238
266
|
|
|
239
267
|
|
|
240
268
|
def test_predict_callback_and_setup():
|
|
241
|
-
|
|
242
|
-
|
|
269
|
+
"""Test callback functionality during YOLO prediction."""
|
|
270
|
+
|
|
271
|
+
def on_predict_batch_end(predictor):
|
|
272
|
+
"""Callback function that handles operations at the end of a prediction batch."""
|
|
243
273
|
path, im0s, _, _ = predictor.batch
|
|
244
274
|
im0s = im0s if isinstance(im0s, list) else [im0s]
|
|
245
275
|
bs = [predictor.dataset.bs for _ in range(len(path))]
|
|
246
|
-
predictor.results = zip(predictor.results, im0s, bs)
|
|
276
|
+
predictor.results = zip(predictor.results, im0s, bs) # results is List[batch_size]
|
|
247
277
|
|
|
248
278
|
model = YOLO(MODEL)
|
|
249
279
|
model.add_callback('on_predict_batch_end', on_predict_batch_end)
|
|
@@ -259,6 +289,7 @@ def test_predict_callback_and_setup():
|
|
|
259
289
|
|
|
260
290
|
|
|
261
291
|
def test_results():
|
|
292
|
+
"""Test various result formats for the YOLO model."""
|
|
262
293
|
for m in 'yolov8n-pose.pt', 'yolov8n-seg.pt', 'yolov8n.pt', 'yolov8n-cls.pt':
|
|
263
294
|
results = YOLO(WEIGHTS_DIR / m)([SOURCE, SOURCE], imgsz=160)
|
|
264
295
|
for r in results:
|
|
@@ -274,7 +305,7 @@ def test_results():
|
|
|
274
305
|
|
|
275
306
|
@pytest.mark.skipif(not ONLINE, reason='environment is offline')
|
|
276
307
|
def test_data_utils():
|
|
277
|
-
|
|
308
|
+
"""Test utility functions in ultralytics/data/utils.py."""
|
|
278
309
|
from ultralytics.data.utils import HUBDatasetStats, autosplit
|
|
279
310
|
from ultralytics.utils.downloads import zip_directory
|
|
280
311
|
|
|
@@ -294,7 +325,7 @@ def test_data_utils():
|
|
|
294
325
|
|
|
295
326
|
@pytest.mark.skipif(not ONLINE, reason='environment is offline')
|
|
296
327
|
def test_data_converter():
|
|
297
|
-
|
|
328
|
+
"""Test dataset converters."""
|
|
298
329
|
from ultralytics.data.converter import coco80_to_coco91_class, convert_coco
|
|
299
330
|
|
|
300
331
|
file = 'instances_val2017.json'
|
|
@@ -304,6 +335,7 @@ def test_data_converter():
|
|
|
304
335
|
|
|
305
336
|
|
|
306
337
|
def test_data_annotator():
|
|
338
|
+
"""Test automatic data annotation."""
|
|
307
339
|
from ultralytics.data.annotator import auto_annotate
|
|
308
340
|
|
|
309
341
|
auto_annotate(ASSETS,
|
|
@@ -313,7 +345,7 @@ def test_data_annotator():
|
|
|
313
345
|
|
|
314
346
|
|
|
315
347
|
def test_events():
|
|
316
|
-
|
|
348
|
+
"""Test event sending functionality."""
|
|
317
349
|
from ultralytics.hub.utils import Events
|
|
318
350
|
|
|
319
351
|
events = Events()
|
|
@@ -324,6 +356,7 @@ def test_events():
|
|
|
324
356
|
|
|
325
357
|
|
|
326
358
|
def test_cfg_init():
|
|
359
|
+
"""Test configuration initialization utilities."""
|
|
327
360
|
from ultralytics.cfg import check_dict_alignment, copy_default_cfg, smart_value
|
|
328
361
|
|
|
329
362
|
with contextlib.suppress(SyntaxError):
|
|
@@ -334,6 +367,7 @@ def test_cfg_init():
|
|
|
334
367
|
|
|
335
368
|
|
|
336
369
|
def test_utils_init():
|
|
370
|
+
"""Test initialization utilities."""
|
|
337
371
|
from ultralytics.utils import get_git_branch, get_git_origin_url, get_ubuntu_version, is_github_actions_ci
|
|
338
372
|
|
|
339
373
|
get_ubuntu_version()
|
|
@@ -343,26 +377,26 @@ def test_utils_init():
|
|
|
343
377
|
|
|
344
378
|
|
|
345
379
|
def test_utils_checks():
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
check_imshow()
|
|
355
|
-
check_version('ultralytics', '8.0.0')
|
|
356
|
-
print_args()
|
|
380
|
+
"""Test various utility checks."""
|
|
381
|
+
checks.check_yolov5u_filename('yolov5n.pt')
|
|
382
|
+
checks.git_describe(ROOT)
|
|
383
|
+
checks.check_requirements() # check requirements.txt
|
|
384
|
+
checks.check_imgsz([600, 600], max_dim=1)
|
|
385
|
+
checks.check_imshow()
|
|
386
|
+
checks.check_version('ultralytics', '8.0.0')
|
|
387
|
+
checks.print_args()
|
|
388
|
+
# checks.check_imshow(warn=True)
|
|
357
389
|
|
|
358
390
|
|
|
359
391
|
def test_utils_benchmarks():
|
|
392
|
+
"""Test model benchmarking."""
|
|
360
393
|
from ultralytics.utils.benchmarks import ProfileModels
|
|
361
394
|
|
|
362
395
|
ProfileModels(['yolov8n.yaml'], imgsz=32, min_time=1, num_timed_runs=3, num_warmup_runs=1).profile()
|
|
363
396
|
|
|
364
397
|
|
|
365
398
|
def test_utils_torchutils():
|
|
399
|
+
"""Test Torch utility functions."""
|
|
366
400
|
from ultralytics.nn.modules.conv import Conv
|
|
367
401
|
from ultralytics.utils.torch_utils import get_flops_with_torch_profiler, profile, time_sync
|
|
368
402
|
|
|
@@ -376,12 +410,14 @@ def test_utils_torchutils():
|
|
|
376
410
|
|
|
377
411
|
@pytest.mark.skipif(not ONLINE, reason='environment is offline')
|
|
378
412
|
def test_utils_downloads():
|
|
413
|
+
"""Test file download utilities."""
|
|
379
414
|
from ultralytics.utils.downloads import get_google_drive_file_info
|
|
380
415
|
|
|
381
416
|
get_google_drive_file_info('https://drive.google.com/file/d/1cqT-cJgANNrhIHCrEufUYhQ4RqiWG_lJ/view?usp=drive_link')
|
|
382
417
|
|
|
383
418
|
|
|
384
419
|
def test_utils_ops():
|
|
420
|
+
"""Test various operations utilities."""
|
|
385
421
|
from ultralytics.utils.ops import (ltwh2xywh, ltwh2xyxy, make_divisible, xywh2ltwh, xywh2xyxy, xywhn2xyxy,
|
|
386
422
|
xywhr2xyxyxyxy, xyxy2ltwh, xyxy2xywh, xyxy2xywhn, xyxyxyxy2xywhr)
|
|
387
423
|
|
|
@@ -399,6 +435,7 @@ def test_utils_ops():
|
|
|
399
435
|
|
|
400
436
|
|
|
401
437
|
def test_utils_files():
|
|
438
|
+
"""Test file handling utilities."""
|
|
402
439
|
from ultralytics.utils.files import file_age, file_date, get_latest_run, spaces_in_path
|
|
403
440
|
|
|
404
441
|
file_age(SOURCE)
|
|
@@ -412,6 +449,7 @@ def test_utils_files():
|
|
|
412
449
|
|
|
413
450
|
|
|
414
451
|
def test_nn_modules_conv():
|
|
452
|
+
"""Test Convolutional Neural Network modules."""
|
|
415
453
|
from ultralytics.nn.modules.conv import CBAM, Conv2, ConvTranspose, DWConvTranspose2d, Focus
|
|
416
454
|
|
|
417
455
|
c1, c2 = 8, 16 # input and output channels
|
|
@@ -430,6 +468,7 @@ def test_nn_modules_conv():
|
|
|
430
468
|
|
|
431
469
|
|
|
432
470
|
def test_nn_modules_block():
|
|
471
|
+
"""Test Neural Network block modules."""
|
|
433
472
|
from ultralytics.nn.modules.block import C1, C3TR, BottleneckCSP, C3Ghost, C3x
|
|
434
473
|
|
|
435
474
|
c1, c2 = 8, 16 # input and output channels
|
|
@@ -445,9 +484,61 @@ def test_nn_modules_block():
|
|
|
445
484
|
|
|
446
485
|
@pytest.mark.skipif(not ONLINE, reason='environment is offline')
|
|
447
486
|
def test_hub():
|
|
487
|
+
"""Test Ultralytics HUB functionalities."""
|
|
448
488
|
from ultralytics.hub import export_fmts_hub, logout
|
|
449
489
|
from ultralytics.hub.utils import smart_request
|
|
450
490
|
|
|
451
491
|
export_fmts_hub()
|
|
452
492
|
logout()
|
|
453
493
|
smart_request('GET', 'http://github.com', progress=True)
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
@pytest.mark.slow
|
|
497
|
+
@pytest.mark.skipif(not ONLINE, reason='environment is offline')
|
|
498
|
+
def test_triton():
|
|
499
|
+
"""Test NVIDIA Triton Server functionalities."""
|
|
500
|
+
checks.check_requirements('tritonclient[all]')
|
|
501
|
+
import subprocess
|
|
502
|
+
import time
|
|
503
|
+
|
|
504
|
+
from tritonclient.http import InferenceServerClient # noqa
|
|
505
|
+
|
|
506
|
+
# Create variables
|
|
507
|
+
model_name = 'yolo'
|
|
508
|
+
triton_repo_path = TMP / 'triton_repo'
|
|
509
|
+
triton_model_path = triton_repo_path / model_name
|
|
510
|
+
|
|
511
|
+
# Export model to ONNX
|
|
512
|
+
f = YOLO(MODEL).export(format='onnx', dynamic=True)
|
|
513
|
+
|
|
514
|
+
# Prepare Triton repo
|
|
515
|
+
(triton_model_path / '1').mkdir(parents=True, exist_ok=True)
|
|
516
|
+
Path(f).rename(triton_model_path / '1' / 'model.onnx')
|
|
517
|
+
(triton_model_path / 'config.pdtxt').touch()
|
|
518
|
+
|
|
519
|
+
# Define image https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tritonserver
|
|
520
|
+
tag = 'nvcr.io/nvidia/tritonserver:23.09-py3' # 6.4 GB
|
|
521
|
+
|
|
522
|
+
# Pull the image
|
|
523
|
+
subprocess.call(f'docker pull {tag}', shell=True)
|
|
524
|
+
|
|
525
|
+
# Run the Triton server and capture the container ID
|
|
526
|
+
container_id = subprocess.check_output(
|
|
527
|
+
f'docker run -d --rm -v {triton_repo_path}:/models -p 8000:8000 {tag} tritonserver --model-repository=/models',
|
|
528
|
+
shell=True).decode('utf-8').strip()
|
|
529
|
+
|
|
530
|
+
# Wait for the Triton server to start
|
|
531
|
+
triton_client = InferenceServerClient(url='localhost:8000', verbose=False, ssl=False)
|
|
532
|
+
|
|
533
|
+
# Wait until model is ready
|
|
534
|
+
for _ in range(10):
|
|
535
|
+
with contextlib.suppress(Exception):
|
|
536
|
+
assert triton_client.is_model_ready(model_name)
|
|
537
|
+
break
|
|
538
|
+
time.sleep(1)
|
|
539
|
+
|
|
540
|
+
# Check Triton inference
|
|
541
|
+
YOLO(f'http://localhost:8000/{model_name}', 'detect')(SOURCE) # exported model inference
|
|
542
|
+
|
|
543
|
+
# Kill and remove the container at the end of the test
|
|
544
|
+
subprocess.call(f'docker kill {container_id}', shell=True)
|