sunsmarterjieleaf commited on
Commit
71fb51d
Β·
verified Β·
1 Parent(s): 488bbce

Delete tests

Browse files
tests/__init__.py DELETED
@@ -1,22 +0,0 @@
1
- # Ultralytics πŸš€ AGPL-3.0 License - https://ultralytics.com/license
2
-
3
- from ultralytics.utils import ASSETS, ROOT, WEIGHTS_DIR, checks
4
-
5
- # Constants used in tests
6
- MODEL = WEIGHTS_DIR / "path with spaces" / "yolo11n.pt" # test spaces in path
7
- CFG = "yolo11n.yaml"
8
- SOURCE = ASSETS / "bus.jpg"
9
- SOURCES_LIST = [ASSETS / "bus.jpg", ASSETS, ASSETS / "*", ASSETS / "**/*.jpg"]
10
- TMP = (ROOT / "../tests/tmp").resolve() # temp directory for test files
11
- CUDA_IS_AVAILABLE = checks.cuda_is_available()
12
- CUDA_DEVICE_COUNT = checks.cuda_device_count()
13
-
14
- __all__ = (
15
- "MODEL",
16
- "CFG",
17
- "SOURCE",
18
- "SOURCES_LIST",
19
- "TMP",
20
- "CUDA_IS_AVAILABLE",
21
- "CUDA_DEVICE_COUNT",
22
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/conftest.py DELETED
@@ -1,83 +0,0 @@
1
- # Ultralytics πŸš€ AGPL-3.0 License - https://ultralytics.com/license
2
-
3
- import shutil
4
- from pathlib import Path
5
-
6
- from tests import TMP
7
-
8
-
9
- def pytest_addoption(parser):
10
- """
11
- Add custom command-line options to pytest.
12
-
13
- Args:
14
- parser (pytest.config.Parser): The pytest parser object for adding custom command-line options.
15
-
16
- Returns:
17
- (None)
18
- """
19
- parser.addoption("--slow", action="store_true", default=False, help="Run slow tests")
20
-
21
-
22
- def pytest_collection_modifyitems(config, items):
23
- """
24
- Modify the list of test items to exclude tests marked as slow if the --slow option is not specified.
25
-
26
- Args:
27
- config (pytest.config.Config): The pytest configuration object that provides access to command-line options.
28
- items (list): The list of collected pytest item objects to be modified based on the presence of --slow option.
29
-
30
- Returns:
31
- (None) The function modifies the 'items' list in place, and does not return a value.
32
- """
33
- if not config.getoption("--slow"):
34
- # Remove the item entirely from the list of test items if it's marked as 'slow'
35
- items[:] = [item for item in items if "slow" not in item.keywords]
36
-
37
-
38
- def pytest_sessionstart(session):
39
- """
40
- Initialize session configurations for pytest.
41
-
42
- This function is automatically called by pytest after the 'Session' object has been created but before performing
43
- test collection. It sets the initial seeds and prepares the temporary directory for the test session.
44
-
45
- Args:
46
- session (pytest.Session): The pytest session object.
47
-
48
- Returns:
49
- (None)
50
- """
51
- from ultralytics.utils.torch_utils import init_seeds
52
-
53
- init_seeds()
54
- shutil.rmtree(TMP, ignore_errors=True) # delete any existing tests/tmp directory
55
- TMP.mkdir(parents=True, exist_ok=True) # create a new empty directory
56
-
57
-
58
- def pytest_terminal_summary(terminalreporter, exitstatus, config):
59
- """
60
- Cleanup operations after pytest session.
61
-
62
- This function is automatically called by pytest at the end of the entire test session. It removes certain files
63
- and directories used during testing.
64
-
65
- Args:
66
- terminalreporter (pytest.terminal.TerminalReporter): The terminal reporter object used for terminal output.
67
- exitstatus (int): The exit status of the test run.
68
- config (pytest.config.Config): The pytest config object.
69
-
70
- Returns:
71
- (None)
72
- """
73
- from ultralytics.utils import WEIGHTS_DIR
74
-
75
- # Remove files
76
- models = [path for x in ["*.onnx", "*.torchscript"] for path in WEIGHTS_DIR.rglob(x)]
77
- for file in ["decelera_portrait_min.mov", "bus.jpg", "yolo11n.onnx", "yolo11n.torchscript"] + models:
78
- Path(file).unlink(missing_ok=True)
79
-
80
- # Remove directories
81
- models = [path for x in ["*.mlpackage", "*_openvino_model"] for path in WEIGHTS_DIR.rglob(x)]
82
- for directory in [WEIGHTS_DIR / "path with spaces", TMP.parents[1] / ".pytest_cache", TMP] + models:
83
- shutil.rmtree(directory, ignore_errors=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/test_cli.py DELETED
@@ -1,122 +0,0 @@
1
- # Ultralytics πŸš€ AGPL-3.0 License - https://ultralytics.com/license
2
-
3
- import subprocess
4
-
5
- import pytest
6
- from PIL import Image
7
-
8
- from tests import CUDA_DEVICE_COUNT, CUDA_IS_AVAILABLE
9
- from ultralytics.cfg import TASK2DATA, TASK2MODEL, TASKS
10
- from ultralytics.utils import ASSETS, WEIGHTS_DIR, checks
11
- from ultralytics.utils.torch_utils import TORCH_1_9
12
-
13
- # Constants
14
- TASK_MODEL_DATA = [(task, WEIGHTS_DIR / TASK2MODEL[task], TASK2DATA[task]) for task in TASKS]
15
- MODELS = [WEIGHTS_DIR / TASK2MODEL[task] for task in TASKS]
16
-
17
-
18
- def run(cmd):
19
- """Execute a shell command using subprocess."""
20
- subprocess.run(cmd.split(), check=True)
21
-
22
-
23
- def test_special_modes():
24
- """Test various special command-line modes for YOLO functionality."""
25
- run("yolo help")
26
- run("yolo checks")
27
- run("yolo version")
28
- run("yolo settings reset")
29
- run("yolo cfg")
30
-
31
-
32
- @pytest.mark.parametrize("task,model,data", TASK_MODEL_DATA)
33
- def test_train(task, model, data):
34
- """Test YOLO training for different tasks, models, and datasets."""
35
- run(f"yolo train {task} model={model} data={data} imgsz=32 epochs=1 cache=disk")
36
-
37
-
38
- @pytest.mark.parametrize("task,model,data", TASK_MODEL_DATA)
39
- def test_val(task, model, data):
40
- """Test YOLO validation process for specified task, model, and data using a shell command."""
41
- run(f"yolo val {task} model={model} data={data} imgsz=32 save_txt save_json")
42
-
43
-
44
- @pytest.mark.parametrize("task,model,data", TASK_MODEL_DATA)
45
- def test_predict(task, model, data):
46
- """Test YOLO prediction on provided sample assets for specified task and model."""
47
- run(f"yolo predict model={model} source={ASSETS} imgsz=32 save save_crop save_txt")
48
-
49
-
50
- @pytest.mark.parametrize("model", MODELS)
51
- def test_export(model):
52
- """Test exporting a YOLO model to TorchScript format."""
53
- run(f"yolo export model={model} format=torchscript imgsz=32")
54
-
55
-
56
- def test_rtdetr(task="detect", model="yolov8n-rtdetr.yaml", data="coco8.yaml"):
57
- """Test the RTDETR functionality within Ultralytics for detection tasks using specified model and data."""
58
- # Warning: must use imgsz=640 (note also add coma, spaces, fraction=0.25 args to test single-image training)
59
- run(f"yolo train {task} model={model} data={data} --imgsz= 160 epochs =1, cache = disk fraction=0.25")
60
- run(f"yolo predict {task} model={model} source={ASSETS / 'bus.jpg'} imgsz=160 save save_crop save_txt")
61
- if TORCH_1_9:
62
- weights = WEIGHTS_DIR / "rtdetr-l.pt"
63
- run(f"yolo predict {task} model={weights} source={ASSETS / 'bus.jpg'} imgsz=160 save save_crop save_txt")
64
-
65
-
66
- @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="MobileSAM with CLIP is not supported in Python 3.12")
67
- def test_fastsam(task="segment", model=WEIGHTS_DIR / "FastSAM-s.pt", data="coco8-seg.yaml"):
68
- """Test FastSAM model for segmenting objects in images using various prompts within Ultralytics."""
69
- source = ASSETS / "bus.jpg"
70
-
71
- run(f"yolo segment val {task} model={model} data={data} imgsz=32")
72
- run(f"yolo segment predict model={model} source={source} imgsz=32 save save_crop save_txt")
73
-
74
- from ultralytics import FastSAM
75
- from ultralytics.models.sam import Predictor
76
-
77
- # Create a FastSAM model
78
- sam_model = FastSAM(model) # or FastSAM-x.pt
79
-
80
- # Run inference on an image
81
- for s in (source, Image.open(source)):
82
- everything_results = sam_model(s, device="cpu", retina_masks=True, imgsz=320, conf=0.4, iou=0.9)
83
-
84
- # Remove small regions
85
- new_masks, _ = Predictor.remove_small_regions(everything_results[0].masks.data, min_area=20)
86
-
87
- # Run inference with bboxes and points and texts prompt at the same time
88
- sam_model(source, bboxes=[439, 437, 524, 709], points=[[200, 200]], labels=[1], texts="a photo of a dog")
89
-
90
-
91
- def test_mobilesam():
92
- """Test MobileSAM segmentation with point prompts using Ultralytics."""
93
- from ultralytics import SAM
94
-
95
- # Load the model
96
- model = SAM(WEIGHTS_DIR / "mobile_sam.pt")
97
-
98
- # Source
99
- source = ASSETS / "zidane.jpg"
100
-
101
- # Predict a segment based on a 1D point prompt and 1D labels.
102
- model.predict(source, points=[900, 370], labels=[1])
103
-
104
- # Predict a segment based on 3D points and 2D labels (multiple points per object).
105
- model.predict(source, points=[[[900, 370], [1000, 100]]], labels=[[1, 1]])
106
-
107
- # Predict a segment based on a box prompt
108
- model.predict(source, bboxes=[439, 437, 524, 709], save=True)
109
-
110
- # Predict all
111
- # model(source)
112
-
113
-
114
- # Slow Tests -----------------------------------------------------------------------------------------------------------
115
- @pytest.mark.slow
116
- @pytest.mark.parametrize("task,model,data", TASK_MODEL_DATA)
117
- @pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason="CUDA is not available")
118
- @pytest.mark.skipif(CUDA_DEVICE_COUNT < 2, reason="DDP is not available")
119
- def test_train_gpu(task, model, data):
120
- """Test YOLO training on GPU(s) for various tasks and models."""
121
- run(f"yolo train {task} model={model} data={data} imgsz=32 epochs=1 device=0") # single GPU
122
- run(f"yolo train {task} model={model} data={data} imgsz=32 epochs=1 device=0,1") # multi GPU
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/test_cuda.py DELETED
@@ -1,155 +0,0 @@
1
- # Ultralytics πŸš€ AGPL-3.0 License - https://ultralytics.com/license
2
-
3
- from itertools import product
4
- from pathlib import Path
5
-
6
- import pytest
7
- import torch
8
-
9
- from tests import CUDA_DEVICE_COUNT, CUDA_IS_AVAILABLE, MODEL, SOURCE
10
- from ultralytics import YOLO
11
- from ultralytics.cfg import TASK2DATA, TASK2MODEL, TASKS
12
- from ultralytics.utils import ASSETS, WEIGHTS_DIR
13
- from ultralytics.utils.checks import check_amp
14
-
15
-
16
- def test_checks():
17
- """Validate CUDA settings against torch CUDA functions."""
18
- assert torch.cuda.is_available() == CUDA_IS_AVAILABLE
19
- assert torch.cuda.device_count() == CUDA_DEVICE_COUNT
20
-
21
-
22
- @pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason="CUDA is not available")
23
- def test_amp():
24
- """Test AMP training checks."""
25
- model = YOLO("yolo11n.pt").model.cuda()
26
- assert check_amp(model)
27
-
28
-
29
- @pytest.mark.slow
30
- @pytest.mark.skipif(True, reason="CUDA export tests disabled pending additional Ultralytics GPU server availability")
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 model export to TensorRT format for various configurations and run inference."""
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
- workspace=1, # reduce workspace GB for less resource utilization during testing
53
- simplify=True, # use 'onnxslim'
54
- )
55
- YOLO(file)([SOURCE] * batch, imgsz=64 if dynamic else 32) # exported model inference
56
- Path(file).unlink() # cleanup
57
- Path(file).with_suffix(".cache").unlink() if int8 else None # cleanup INT8 cache
58
-
59
-
60
- @pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason="CUDA is not available")
61
- def test_train():
62
- """Test model training on a minimal dataset using available CUDA devices."""
63
- device = 0 if CUDA_DEVICE_COUNT == 1 else [0, 1]
64
- YOLO(MODEL).train(data="coco8.yaml", imgsz=64, epochs=1, device=device) # requires imgsz>=64
65
-
66
-
67
- @pytest.mark.slow
68
- @pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason="CUDA is not available")
69
- def test_predict_multiple_devices():
70
- """Validate model prediction consistency across CPU and CUDA devices."""
71
- model = YOLO("yolo11n.pt")
72
- model = model.cpu()
73
- assert str(model.device) == "cpu"
74
- _ = model(SOURCE) # CPU inference
75
- assert str(model.device) == "cpu"
76
-
77
- model = model.to("cuda:0")
78
- assert str(model.device) == "cuda:0"
79
- _ = model(SOURCE) # CUDA inference
80
- assert str(model.device) == "cuda:0"
81
-
82
- model = model.cpu()
83
- assert str(model.device) == "cpu"
84
- _ = model(SOURCE) # CPU inference
85
- assert str(model.device) == "cpu"
86
-
87
- model = model.cuda()
88
- assert str(model.device) == "cuda:0"
89
- _ = model(SOURCE) # CUDA inference
90
- assert str(model.device) == "cuda:0"
91
-
92
-
93
- @pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason="CUDA is not available")
94
- def test_autobatch():
95
- """Check optimal batch size for YOLO model training using autobatch utility."""
96
- from ultralytics.utils.autobatch import check_train_batch_size
97
-
98
- check_train_batch_size(YOLO(MODEL).model.cuda(), imgsz=128, amp=True)
99
-
100
-
101
- @pytest.mark.slow
102
- @pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason="CUDA is not available")
103
- def test_utils_benchmarks():
104
- """Profile YOLO models for performance benchmarks."""
105
- from ultralytics.utils.benchmarks import ProfileModels
106
-
107
- # Pre-export a dynamic engine model to use dynamic inference
108
- YOLO(MODEL).export(format="engine", imgsz=32, dynamic=True, batch=1)
109
- ProfileModels([MODEL], imgsz=32, half=False, min_time=1, num_timed_runs=3, num_warmup_runs=1).profile()
110
-
111
-
112
- @pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason="CUDA is not available")
113
- def test_predict_sam():
114
- """Test SAM model predictions using different prompts, including bounding boxes and point annotations."""
115
- from ultralytics import SAM
116
- from ultralytics.models.sam import Predictor as SAMPredictor
117
-
118
- # Load a model
119
- model = SAM(WEIGHTS_DIR / "sam2.1_b.pt")
120
-
121
- # Display model information (optional)
122
- model.info()
123
-
124
- # Run inference
125
- model(SOURCE, device=0)
126
-
127
- # Run inference with bboxes prompt
128
- model(SOURCE, bboxes=[439, 437, 524, 709], device=0)
129
-
130
- # Run inference with no labels
131
- model(ASSETS / "zidane.jpg", points=[900, 370], device=0)
132
-
133
- # Run inference with 1D points and 1D labels
134
- model(ASSETS / "zidane.jpg", points=[900, 370], labels=[1], device=0)
135
-
136
- # Run inference with 2D points and 1D labels
137
- model(ASSETS / "zidane.jpg", points=[[900, 370]], labels=[1], device=0)
138
-
139
- # Run inference with multiple 2D points and 1D labels
140
- model(ASSETS / "zidane.jpg", points=[[400, 370], [900, 370]], labels=[1, 1], device=0)
141
-
142
- # Run inference with 3D points and 2D labels (multiple points per object)
143
- model(ASSETS / "zidane.jpg", points=[[[900, 370], [1000, 100]]], labels=[[1, 1]], device=0)
144
-
145
- # Create SAMPredictor
146
- overrides = dict(conf=0.25, task="segment", mode="predict", imgsz=1024, model=WEIGHTS_DIR / "mobile_sam.pt")
147
- predictor = SAMPredictor(overrides=overrides)
148
-
149
- # Set image
150
- predictor.set_image(ASSETS / "zidane.jpg") # set with image file
151
- # predictor(bboxes=[439, 437, 524, 709])
152
- # predictor(points=[900, 370], labels=[1])
153
-
154
- # Reset image
155
- predictor.reset_image()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/test_engine.py DELETED
@@ -1,131 +0,0 @@
1
- # Ultralytics πŸš€ AGPL-3.0 License - https://ultralytics.com/license
2
-
3
- import sys
4
- from unittest import mock
5
-
6
- from tests import MODEL
7
- from ultralytics import YOLO
8
- from ultralytics.cfg import get_cfg
9
- from ultralytics.engine.exporter import Exporter
10
- from ultralytics.models.yolo import classify, detect, segment
11
- from ultralytics.utils import ASSETS, DEFAULT_CFG, WEIGHTS_DIR
12
-
13
-
14
- def test_func(*args): # noqa
15
- """Test function callback for evaluating YOLO model performance metrics."""
16
- print("callback test passed")
17
-
18
-
19
- def test_export():
20
- """Tests the model exporting function by adding a callback and asserting its execution."""
21
- exporter = Exporter()
22
- exporter.add_callback("on_export_start", test_func)
23
- assert test_func in exporter.callbacks["on_export_start"], "callback test failed"
24
- f = exporter(model=YOLO("yolo11n.yaml").model)
25
- YOLO(f)(ASSETS) # exported model inference
26
-
27
-
28
- def test_detect():
29
- """Test YOLO object detection training, validation, and prediction functionality."""
30
- overrides = {"data": "coco8.yaml", "model": "yolo11n.yaml", "imgsz": 32, "epochs": 1, "save": False}
31
- cfg = get_cfg(DEFAULT_CFG)
32
- cfg.data = "coco8.yaml"
33
- cfg.imgsz = 32
34
-
35
- # Trainer
36
- trainer = detect.DetectionTrainer(overrides=overrides)
37
- trainer.add_callback("on_train_start", test_func)
38
- assert test_func in trainer.callbacks["on_train_start"], "callback test failed"
39
- trainer.train()
40
-
41
- # Validator
42
- val = detect.DetectionValidator(args=cfg)
43
- val.add_callback("on_val_start", test_func)
44
- assert test_func in val.callbacks["on_val_start"], "callback test failed"
45
- val(model=trainer.best) # validate best.pt
46
-
47
- # Predictor
48
- pred = detect.DetectionPredictor(overrides={"imgsz": [64, 64]})
49
- pred.add_callback("on_predict_start", test_func)
50
- assert test_func in pred.callbacks["on_predict_start"], "callback test failed"
51
- # Confirm there is no issue with sys.argv being empty.
52
- with mock.patch.object(sys, "argv", []):
53
- result = pred(source=ASSETS, model=MODEL)
54
- assert len(result), "predictor test failed"
55
-
56
- overrides["resume"] = trainer.last
57
- trainer = detect.DetectionTrainer(overrides=overrides)
58
- try:
59
- trainer.train()
60
- except Exception as e:
61
- print(f"Expected exception caught: {e}")
62
- return
63
-
64
- Exception("Resume test failed!")
65
-
66
-
67
- def test_segment():
68
- """Tests image segmentation training, validation, and prediction pipelines using YOLO models."""
69
- overrides = {"data": "coco8-seg.yaml", "model": "yolo11n-seg.yaml", "imgsz": 32, "epochs": 1, "save": False}
70
- cfg = get_cfg(DEFAULT_CFG)
71
- cfg.data = "coco8-seg.yaml"
72
- cfg.imgsz = 32
73
- # YOLO(CFG_SEG).train(**overrides) # works
74
-
75
- # Trainer
76
- trainer = segment.SegmentationTrainer(overrides=overrides)
77
- trainer.add_callback("on_train_start", test_func)
78
- assert test_func in trainer.callbacks["on_train_start"], "callback test failed"
79
- trainer.train()
80
-
81
- # Validator
82
- val = segment.SegmentationValidator(args=cfg)
83
- val.add_callback("on_val_start", test_func)
84
- assert test_func in val.callbacks["on_val_start"], "callback test failed"
85
- val(model=trainer.best) # validate best.pt
86
-
87
- # Predictor
88
- pred = segment.SegmentationPredictor(overrides={"imgsz": [64, 64]})
89
- pred.add_callback("on_predict_start", test_func)
90
- assert test_func in pred.callbacks["on_predict_start"], "callback test failed"
91
- result = pred(source=ASSETS, model=WEIGHTS_DIR / "yolo11n-seg.pt")
92
- assert len(result), "predictor test failed"
93
-
94
- # Test resume
95
- overrides["resume"] = trainer.last
96
- trainer = segment.SegmentationTrainer(overrides=overrides)
97
- try:
98
- trainer.train()
99
- except Exception as e:
100
- print(f"Expected exception caught: {e}")
101
- return
102
-
103
- Exception("Resume test failed!")
104
-
105
-
106
- def test_classify():
107
- """Test image classification including training, validation, and prediction phases."""
108
- overrides = {"data": "imagenet10", "model": "yolo11n-cls.yaml", "imgsz": 32, "epochs": 1, "save": False}
109
- cfg = get_cfg(DEFAULT_CFG)
110
- cfg.data = "imagenet10"
111
- cfg.imgsz = 32
112
- # YOLO(CFG_SEG).train(**overrides) # works
113
-
114
- # Trainer
115
- trainer = classify.ClassificationTrainer(overrides=overrides)
116
- trainer.add_callback("on_train_start", test_func)
117
- assert test_func in trainer.callbacks["on_train_start"], "callback test failed"
118
- trainer.train()
119
-
120
- # Validator
121
- val = classify.ClassificationValidator(args=cfg)
122
- val.add_callback("on_val_start", test_func)
123
- assert test_func in val.callbacks["on_val_start"], "callback test failed"
124
- val(model=trainer.best)
125
-
126
- # Predictor
127
- pred = classify.ClassificationPredictor(overrides={"imgsz": [64, 64]})
128
- pred.add_callback("on_predict_start", test_func)
129
- assert test_func in pred.callbacks["on_predict_start"], "callback test failed"
130
- result = pred(source=ASSETS, model=trainer.best)
131
- assert len(result), "predictor test failed"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/test_exports.py DELETED
@@ -1,216 +0,0 @@
1
- # Ultralytics πŸš€ AGPL-3.0 License - https://ultralytics.com/license
2
-
3
- import shutil
4
- import uuid
5
- from itertools import product
6
- from pathlib import Path
7
-
8
- import pytest
9
-
10
- from tests import MODEL, SOURCE
11
- from ultralytics import YOLO
12
- from ultralytics.cfg import TASK2DATA, TASK2MODEL, TASKS
13
- from ultralytics.utils import (
14
- IS_RASPBERRYPI,
15
- LINUX,
16
- MACOS,
17
- WINDOWS,
18
- checks,
19
- )
20
- from ultralytics.utils.torch_utils import TORCH_1_9, TORCH_1_13
21
-
22
-
23
- def test_export_torchscript():
24
- """Test YOLO model exporting to TorchScript format for compatibility and correctness."""
25
- file = YOLO(MODEL).export(format="torchscript", optimize=False, imgsz=32)
26
- YOLO(file)(SOURCE, imgsz=32) # exported model inference
27
-
28
-
29
- def test_export_onnx():
30
- """Test YOLO model export to ONNX format with dynamic axes."""
31
- file = YOLO(MODEL).export(format="onnx", dynamic=True, imgsz=32)
32
- YOLO(file)(SOURCE, imgsz=32) # exported model inference
33
-
34
-
35
- @pytest.mark.skipif(not TORCH_1_13, reason="OpenVINO requires torch>=1.13")
36
- def test_export_openvino():
37
- """Test YOLO exports to OpenVINO format for model inference compatibility."""
38
- file = YOLO(MODEL).export(format="openvino", imgsz=32)
39
- YOLO(file)(SOURCE, imgsz=32) # exported model inference
40
-
41
-
42
- @pytest.mark.slow
43
- @pytest.mark.skipif(not TORCH_1_13, reason="OpenVINO requires torch>=1.13")
44
- @pytest.mark.parametrize(
45
- "task, dynamic, int8, half, batch",
46
- [ # generate all combinations but exclude those where both int8 and half are True
47
- (task, dynamic, int8, half, batch)
48
- for task, dynamic, int8, half, batch in product(TASKS, [True, False], [True, False], [True, False], [1, 2])
49
- if not (int8 and half) # exclude cases where both int8 and half are True
50
- ],
51
- )
52
- def test_export_openvino_matrix(task, dynamic, int8, half, batch):
53
- """Test YOLO model exports to OpenVINO under various configuration matrix conditions."""
54
- file = YOLO(TASK2MODEL[task]).export(
55
- format="openvino",
56
- imgsz=32,
57
- dynamic=dynamic,
58
- int8=int8,
59
- half=half,
60
- batch=batch,
61
- data=TASK2DATA[task],
62
- )
63
- if WINDOWS:
64
- # Use unique filenames due to Windows file permissions bug possibly due to latent threaded use
65
- # See https://github.com/ultralytics/ultralytics/actions/runs/8957949304/job/24601616830?pr=10423
66
- file = Path(file)
67
- file = file.rename(file.with_stem(f"{file.stem}-{uuid.uuid4()}"))
68
- YOLO(file)([SOURCE] * batch, imgsz=64 if dynamic else 32) # exported model inference
69
- shutil.rmtree(file, ignore_errors=True) # retry in case of potential lingering multi-threaded file usage errors
70
-
71
-
72
- @pytest.mark.slow
73
- @pytest.mark.parametrize(
74
- "task, dynamic, int8, half, batch, simplify", product(TASKS, [True, False], [False], [False], [1, 2], [True, False])
75
- )
76
- def test_export_onnx_matrix(task, dynamic, int8, half, batch, simplify):
77
- """Test YOLO exports to ONNX format with various configurations and parameters."""
78
- file = YOLO(TASK2MODEL[task]).export(
79
- format="onnx",
80
- imgsz=32,
81
- dynamic=dynamic,
82
- int8=int8,
83
- half=half,
84
- batch=batch,
85
- simplify=simplify,
86
- )
87
- YOLO(file)([SOURCE] * batch, imgsz=64 if dynamic else 32) # exported model inference
88
- Path(file).unlink() # cleanup
89
-
90
-
91
- @pytest.mark.slow
92
- @pytest.mark.parametrize("task, dynamic, int8, half, batch", product(TASKS, [False], [False], [False], [1, 2]))
93
- def test_export_torchscript_matrix(task, dynamic, int8, half, batch):
94
- """Tests YOLO model exports to TorchScript format under varied configurations."""
95
- file = YOLO(TASK2MODEL[task]).export(
96
- format="torchscript",
97
- imgsz=32,
98
- dynamic=dynamic,
99
- int8=int8,
100
- half=half,
101
- batch=batch,
102
- )
103
- YOLO(file)([SOURCE] * 3, imgsz=64 if dynamic else 32) # exported model inference at batch=3
104
- Path(file).unlink() # cleanup
105
-
106
-
107
- @pytest.mark.slow
108
- @pytest.mark.skipif(not MACOS, reason="CoreML inference only supported on macOS")
109
- @pytest.mark.skipif(not TORCH_1_9, reason="CoreML>=7.2 not supported with PyTorch<=1.8")
110
- @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="CoreML not supported in Python 3.12")
111
- @pytest.mark.parametrize(
112
- "task, dynamic, int8, half, batch",
113
- [ # generate all combinations but exclude those where both int8 and half are True
114
- (task, dynamic, int8, half, batch)
115
- for task, dynamic, int8, half, batch in product(TASKS, [False], [True, False], [True, False], [1])
116
- if not (int8 and half) # exclude cases where both int8 and half are True
117
- ],
118
- )
119
- def test_export_coreml_matrix(task, dynamic, int8, half, batch):
120
- """Test YOLO exports to CoreML format with various parameter configurations."""
121
- file = YOLO(TASK2MODEL[task]).export(
122
- format="coreml",
123
- imgsz=32,
124
- dynamic=dynamic,
125
- int8=int8,
126
- half=half,
127
- batch=batch,
128
- )
129
- YOLO(file)([SOURCE] * batch, imgsz=32) # exported model inference at batch=3
130
- shutil.rmtree(file) # cleanup
131
-
132
-
133
- @pytest.mark.slow
134
- @pytest.mark.skipif(not checks.IS_PYTHON_MINIMUM_3_10, reason="TFLite export requires Python>=3.10")
135
- @pytest.mark.skipif(not LINUX, reason="Test disabled as TF suffers from install conflicts on Windows and macOS")
136
- @pytest.mark.parametrize(
137
- "task, dynamic, int8, half, batch",
138
- [ # generate all combinations but exclude those where both int8 and half are True
139
- (task, dynamic, int8, half, batch)
140
- for task, dynamic, int8, half, batch in product(TASKS, [False], [True, False], [True, False], [1])
141
- if not (int8 and half) # exclude cases where both int8 and half are True
142
- ],
143
- )
144
- def test_export_tflite_matrix(task, dynamic, int8, half, batch):
145
- """Test YOLO exports to TFLite format considering various export configurations."""
146
- file = YOLO(TASK2MODEL[task]).export(
147
- format="tflite",
148
- imgsz=32,
149
- dynamic=dynamic,
150
- int8=int8,
151
- half=half,
152
- batch=batch,
153
- )
154
- YOLO(file)([SOURCE] * batch, imgsz=32) # exported model inference at batch=3
155
- Path(file).unlink() # cleanup
156
-
157
-
158
- @pytest.mark.skipif(not TORCH_1_9, reason="CoreML>=7.2 not supported with PyTorch<=1.8")
159
- @pytest.mark.skipif(WINDOWS, reason="CoreML not supported on Windows") # RuntimeError: BlobWriter not loaded
160
- @pytest.mark.skipif(IS_RASPBERRYPI, reason="CoreML not supported on Raspberry Pi")
161
- @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="CoreML not supported in Python 3.12")
162
- def test_export_coreml():
163
- """Test YOLO exports to CoreML format, optimized for macOS only."""
164
- if MACOS:
165
- file = YOLO(MODEL).export(format="coreml", imgsz=32)
166
- YOLO(file)(SOURCE, imgsz=32) # model prediction only supported on macOS for nms=False models
167
- else:
168
- YOLO(MODEL).export(format="coreml", nms=True, imgsz=32)
169
-
170
-
171
- @pytest.mark.skipif(not checks.IS_PYTHON_MINIMUM_3_10, reason="TFLite export requires Python>=3.10")
172
- @pytest.mark.skipif(not LINUX, reason="Test disabled as TF suffers from install conflicts on Windows and macOS")
173
- def test_export_tflite():
174
- """Test YOLO exports to TFLite format under specific OS and Python version conditions."""
175
- model = YOLO(MODEL)
176
- file = model.export(format="tflite", imgsz=32)
177
- YOLO(file)(SOURCE, imgsz=32)
178
-
179
-
180
- @pytest.mark.skipif(True, reason="Test disabled")
181
- @pytest.mark.skipif(not LINUX, reason="TF suffers from install conflicts on Windows and macOS")
182
- def test_export_pb():
183
- """Test YOLO exports to TensorFlow's Protobuf (*.pb) format."""
184
- model = YOLO(MODEL)
185
- file = model.export(format="pb", imgsz=32)
186
- YOLO(file)(SOURCE, imgsz=32)
187
-
188
-
189
- @pytest.mark.skipif(True, reason="Test disabled as Paddle protobuf and ONNX protobuf requirements conflict.")
190
- def test_export_paddle():
191
- """Test YOLO exports to Paddle format, noting protobuf conflicts with ONNX."""
192
- YOLO(MODEL).export(format="paddle", imgsz=32)
193
-
194
-
195
- @pytest.mark.slow
196
- @pytest.mark.skipif(IS_RASPBERRYPI, reason="MNN not supported on Raspberry Pi")
197
- def test_export_mnn():
198
- """Test YOLO exports to MNN format (WARNING: MNN test must precede NCNN test or CI error on Windows)."""
199
- file = YOLO(MODEL).export(format="mnn", imgsz=32)
200
- YOLO(file)(SOURCE, imgsz=32) # exported model inference
201
-
202
-
203
- @pytest.mark.slow
204
- def test_export_ncnn():
205
- """Test YOLO exports to NCNN format."""
206
- file = YOLO(MODEL).export(format="ncnn", imgsz=32)
207
- YOLO(file)(SOURCE, imgsz=32) # exported model inference
208
-
209
-
210
- @pytest.mark.skipif(True, reason="Test disabled as keras and tensorflow version conflicts with tflite export.")
211
- @pytest.mark.skipif(not LINUX or MACOS, reason="Skipping test on Windows and Macos")
212
- def test_export_imx():
213
- """Test YOLOv8n exports to IMX format."""
214
- model = YOLO("yolov8n.pt")
215
- file = model.export(format="imx", imgsz=32)
216
- YOLO(file)(SOURCE, imgsz=32)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/test_integrations.py DELETED
@@ -1,150 +0,0 @@
1
- # Ultralytics πŸš€ AGPL-3.0 License - https://ultralytics.com/license
2
-
3
- import contextlib
4
- import os
5
- import subprocess
6
- import time
7
- from pathlib import Path
8
-
9
- import pytest
10
-
11
- from tests import MODEL, SOURCE, TMP
12
- from ultralytics import YOLO, download
13
- from ultralytics.utils import DATASETS_DIR, SETTINGS
14
- from ultralytics.utils.checks import check_requirements
15
-
16
-
17
- @pytest.mark.skipif(not check_requirements("ray", install=False), reason="ray[tune] not installed")
18
- def test_model_ray_tune():
19
- """Tune YOLO model using Ray for hyperparameter optimization."""
20
- YOLO("yolo11n-cls.yaml").tune(
21
- use_ray=True, data="imagenet10", grace_period=1, iterations=1, imgsz=32, epochs=1, plots=False, device="cpu"
22
- )
23
-
24
-
25
- @pytest.mark.skipif(not check_requirements("mlflow", install=False), reason="mlflow not installed")
26
- def test_mlflow():
27
- """Test training with MLflow tracking enabled (see https://mlflow.org/ for details)."""
28
- SETTINGS["mlflow"] = True
29
- YOLO("yolo11n-cls.yaml").train(data="imagenet10", imgsz=32, epochs=3, plots=False, device="cpu")
30
- SETTINGS["mlflow"] = False
31
-
32
-
33
- @pytest.mark.skipif(True, reason="Test failing in scheduled CI https://github.com/ultralytics/ultralytics/pull/8868")
34
- @pytest.mark.skipif(not check_requirements("mlflow", install=False), reason="mlflow not installed")
35
- def test_mlflow_keep_run_active():
36
- """Ensure MLflow run status matches MLFLOW_KEEP_RUN_ACTIVE environment variable settings."""
37
- import mlflow
38
-
39
- SETTINGS["mlflow"] = True
40
- run_name = "Test Run"
41
- os.environ["MLFLOW_RUN"] = run_name
42
-
43
- # Test with MLFLOW_KEEP_RUN_ACTIVE=True
44
- os.environ["MLFLOW_KEEP_RUN_ACTIVE"] = "True"
45
- YOLO("yolo11n-cls.yaml").train(data="imagenet10", imgsz=32, epochs=1, plots=False, device="cpu")
46
- status = mlflow.active_run().info.status
47
- assert status == "RUNNING", "MLflow run should be active when MLFLOW_KEEP_RUN_ACTIVE=True"
48
-
49
- run_id = mlflow.active_run().info.run_id
50
-
51
- # Test with MLFLOW_KEEP_RUN_ACTIVE=False
52
- os.environ["MLFLOW_KEEP_RUN_ACTIVE"] = "False"
53
- YOLO("yolo11n-cls.yaml").train(data="imagenet10", imgsz=32, epochs=1, plots=False, device="cpu")
54
- status = mlflow.get_run(run_id=run_id).info.status
55
- assert status == "FINISHED", "MLflow run should be ended when MLFLOW_KEEP_RUN_ACTIVE=False"
56
-
57
- # Test with MLFLOW_KEEP_RUN_ACTIVE not set
58
- os.environ.pop("MLFLOW_KEEP_RUN_ACTIVE", None)
59
- YOLO("yolo11n-cls.yaml").train(data="imagenet10", imgsz=32, epochs=1, plots=False, device="cpu")
60
- status = mlflow.get_run(run_id=run_id).info.status
61
- assert status == "FINISHED", "MLflow run should be ended by default when MLFLOW_KEEP_RUN_ACTIVE is not set"
62
- SETTINGS["mlflow"] = False
63
-
64
-
65
- @pytest.mark.skipif(not check_requirements("tritonclient", install=False), reason="tritonclient[all] not installed")
66
- def test_triton():
67
- """
68
- Test NVIDIA Triton Server functionalities with YOLO model.
69
-
70
- See https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tritonserver.
71
- """
72
- check_requirements("tritonclient[all]")
73
- from tritonclient.http import InferenceServerClient # noqa
74
-
75
- # Create variables
76
- model_name = "yolo"
77
- triton_repo = TMP / "triton_repo" # Triton repo path
78
- triton_model = triton_repo / model_name # Triton model path
79
-
80
- # Export model to ONNX
81
- f = YOLO(MODEL).export(format="onnx", dynamic=True)
82
-
83
- # Prepare Triton repo
84
- (triton_model / "1").mkdir(parents=True, exist_ok=True)
85
- Path(f).rename(triton_model / "1" / "model.onnx")
86
- (triton_model / "config.pbtxt").touch()
87
-
88
- # Define image https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tritonserver
89
- tag = "nvcr.io/nvidia/tritonserver:23.09-py3" # 6.4 GB
90
-
91
- # Pull the image
92
- subprocess.call(f"docker pull {tag}", shell=True)
93
-
94
- # Run the Triton server and capture the container ID
95
- container_id = (
96
- subprocess.check_output(
97
- f"docker run -d --rm -v {triton_repo}:/models -p 8000:8000 {tag} tritonserver --model-repository=/models",
98
- shell=True,
99
- )
100
- .decode("utf-8")
101
- .strip()
102
- )
103
-
104
- # Wait for the Triton server to start
105
- triton_client = InferenceServerClient(url="localhost:8000", verbose=False, ssl=False)
106
-
107
- # Wait until model is ready
108
- for _ in range(10):
109
- with contextlib.suppress(Exception):
110
- assert triton_client.is_model_ready(model_name)
111
- break
112
- time.sleep(1)
113
-
114
- # Check Triton inference
115
- YOLO(f"http://localhost:8000/{model_name}", "detect")(SOURCE) # exported model inference
116
-
117
- # Kill and remove the container at the end of the test
118
- subprocess.call(f"docker kill {container_id}", shell=True)
119
-
120
-
121
- @pytest.mark.skipif(not check_requirements("pycocotools", install=False), reason="pycocotools not installed")
122
- def test_pycocotools():
123
- """Validate YOLO model predictions on COCO dataset using pycocotools."""
124
- from ultralytics.models.yolo.detect import DetectionValidator
125
- from ultralytics.models.yolo.pose import PoseValidator
126
- from ultralytics.models.yolo.segment import SegmentationValidator
127
-
128
- # Download annotations after each dataset downloads first
129
- url = "https://github.com/ultralytics/assets/releases/download/v0.0.0/"
130
-
131
- args = {"model": "yolo11n.pt", "data": "coco8.yaml", "save_json": True, "imgsz": 64}
132
- validator = DetectionValidator(args=args)
133
- validator()
134
- validator.is_coco = True
135
- download(f"{url}instances_val2017.json", dir=DATASETS_DIR / "coco8/annotations")
136
- _ = validator.eval_json(validator.stats)
137
-
138
- args = {"model": "yolo11n-seg.pt", "data": "coco8-seg.yaml", "save_json": True, "imgsz": 64}
139
- validator = SegmentationValidator(args=args)
140
- validator()
141
- validator.is_coco = True
142
- download(f"{url}instances_val2017.json", dir=DATASETS_DIR / "coco8-seg/annotations")
143
- _ = validator.eval_json(validator.stats)
144
-
145
- args = {"model": "yolo11n-pose.pt", "data": "coco8-pose.yaml", "save_json": True, "imgsz": 64}
146
- validator = PoseValidator(args=args)
147
- validator()
148
- validator.is_coco = True
149
- download(f"{url}person_keypoints_val2017.json", dir=DATASETS_DIR / "coco8-pose/annotations")
150
- _ = validator.eval_json(validator.stats)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/test_python.py DELETED
@@ -1,615 +0,0 @@
1
- # Ultralytics πŸš€ AGPL-3.0 License - https://ultralytics.com/license
2
-
3
- import contextlib
4
- import csv
5
- import urllib
6
- from copy import copy
7
- from pathlib import Path
8
-
9
- import cv2
10
- import numpy as np
11
- import pytest
12
- import torch
13
- import yaml
14
- from PIL import Image
15
-
16
- from tests import CFG, MODEL, SOURCE, SOURCES_LIST, TMP
17
- from ultralytics import RTDETR, YOLO
18
- from ultralytics.cfg import MODELS, TASK2DATA, TASKS
19
- from ultralytics.data.build import load_inference_source
20
- from ultralytics.utils import (
21
- ASSETS,
22
- DEFAULT_CFG,
23
- DEFAULT_CFG_PATH,
24
- LOGGER,
25
- ONLINE,
26
- ROOT,
27
- WEIGHTS_DIR,
28
- WINDOWS,
29
- checks,
30
- is_dir_writeable,
31
- is_github_action_running,
32
- )
33
- from ultralytics.utils.downloads import download
34
- from ultralytics.utils.torch_utils import TORCH_1_9
35
-
36
- IS_TMP_WRITEABLE = is_dir_writeable(TMP) # WARNING: must be run once tests start as TMP does not exist on tests/init
37
-
38
-
39
- def test_model_forward():
40
- """Test the forward pass of the YOLO model."""
41
- model = YOLO(CFG)
42
- model(source=None, imgsz=32, augment=True) # also test no source and augment
43
-
44
-
45
- def test_model_methods():
46
- """Test various methods and properties of the YOLO model to ensure correct functionality."""
47
- model = YOLO(MODEL)
48
-
49
- # Model methods
50
- model.info(verbose=True, detailed=True)
51
- model = model.reset_weights()
52
- model = model.load(MODEL)
53
- model.to("cpu")
54
- model.fuse()
55
- model.clear_callback("on_train_start")
56
- model.reset_callbacks()
57
-
58
- # Model properties
59
- _ = model.names
60
- _ = model.device
61
- _ = model.transforms
62
- _ = model.task_map
63
-
64
-
65
- def test_model_profile():
66
- """Test profiling of the YOLO model with `profile=True` to assess performance and resource usage."""
67
- from ultralytics.nn.tasks import DetectionModel
68
-
69
- model = DetectionModel() # build model
70
- im = torch.randn(1, 3, 64, 64) # requires min imgsz=64
71
- _ = model.predict(im, profile=True)
72
-
73
-
74
- @pytest.mark.skipif(not IS_TMP_WRITEABLE, reason="directory is not writeable")
75
- def test_predict_txt():
76
- """Tests YOLO predictions with file, directory, and pattern sources listed in a text file."""
77
- file = TMP / "sources_multi_row.txt"
78
- with open(file, "w") as f:
79
- for src in SOURCES_LIST:
80
- f.write(f"{src}\n")
81
- results = YOLO(MODEL)(source=file, imgsz=32)
82
- assert len(results) == 7 # 1 + 2 + 2 + 2 = 7 images
83
-
84
-
85
- @pytest.mark.skipif(True, reason="disabled for testing")
86
- @pytest.mark.skipif(not IS_TMP_WRITEABLE, reason="directory is not writeable")
87
- def test_predict_csv_multi_row():
88
- """Tests YOLO predictions with sources listed in multiple rows of a CSV file."""
89
- file = TMP / "sources_multi_row.csv"
90
- with open(file, "w", newline="") as f:
91
- writer = csv.writer(f)
92
- writer.writerow(["source"])
93
- writer.writerows([[src] for src in SOURCES_LIST])
94
- results = YOLO(MODEL)(source=file, imgsz=32)
95
- assert len(results) == 7 # 1 + 2 + 2 + 2 = 7 images
96
-
97
-
98
- @pytest.mark.skipif(True, reason="disabled for testing")
99
- @pytest.mark.skipif(not IS_TMP_WRITEABLE, reason="directory is not writeable")
100
- def test_predict_csv_single_row():
101
- """Tests YOLO predictions with sources listed in a single row of a CSV file."""
102
- file = TMP / "sources_single_row.csv"
103
- with open(file, "w", newline="") as f:
104
- writer = csv.writer(f)
105
- writer.writerow(SOURCES_LIST)
106
- results = YOLO(MODEL)(source=file, imgsz=32)
107
- assert len(results) == 7 # 1 + 2 + 2 + 2 = 7 images
108
-
109
-
110
- @pytest.mark.parametrize("model_name", MODELS)
111
- def test_predict_img(model_name):
112
- """Test YOLO model predictions on various image input types and sources, including online images."""
113
- model = YOLO(WEIGHTS_DIR / model_name)
114
- im = cv2.imread(str(SOURCE)) # uint8 numpy array
115
- assert len(model(source=Image.open(SOURCE), save=True, verbose=True, imgsz=32)) == 1 # PIL
116
- assert len(model(source=im, save=True, save_txt=True, imgsz=32)) == 1 # ndarray
117
- assert len(model(torch.rand((2, 3, 32, 32)), imgsz=32)) == 2 # batch-size 2 Tensor, FP32 0.0-1.0 RGB order
118
- assert len(model(source=[im, im], save=True, save_txt=True, imgsz=32)) == 2 # batch
119
- assert len(list(model(source=[im, im], save=True, stream=True, imgsz=32))) == 2 # stream
120
- assert len(model(torch.zeros(320, 640, 3).numpy().astype(np.uint8), imgsz=32)) == 1 # tensor to numpy
121
- batch = [
122
- str(SOURCE), # filename
123
- Path(SOURCE), # Path
124
- "https://github.com/ultralytics/assets/releases/download/v0.0.0/zidane.jpg" if ONLINE else SOURCE, # URI
125
- cv2.imread(str(SOURCE)), # OpenCV
126
- Image.open(SOURCE), # PIL
127
- np.zeros((320, 640, 3), dtype=np.uint8), # numpy
128
- ]
129
- assert len(model(batch, imgsz=32)) == len(batch) # multiple sources in a batch
130
-
131
-
132
- @pytest.mark.parametrize("model", MODELS)
133
- def test_predict_visualize(model):
134
- """Test model prediction methods with 'visualize=True' to generate and display prediction visualizations."""
135
- YOLO(WEIGHTS_DIR / model)(SOURCE, imgsz=32, visualize=True)
136
-
137
-
138
- def test_predict_grey_and_4ch():
139
- """Test YOLO prediction on SOURCE converted to greyscale and 4-channel images with various filenames."""
140
- im = Image.open(SOURCE)
141
- directory = TMP / "im4"
142
- directory.mkdir(parents=True, exist_ok=True)
143
-
144
- source_greyscale = directory / "greyscale.jpg"
145
- source_rgba = directory / "4ch.png"
146
- source_non_utf = directory / "non_UTF_ζ΅‹θ―•ζ–‡δ»Ά_tΓ©st_image.jpg"
147
- source_spaces = directory / "image with spaces.jpg"
148
-
149
- im.convert("L").save(source_greyscale) # greyscale
150
- im.convert("RGBA").save(source_rgba) # 4-ch PNG with alpha
151
- im.save(source_non_utf) # non-UTF characters in filename
152
- im.save(source_spaces) # spaces in filename
153
-
154
- # Inference
155
- model = YOLO(MODEL)
156
- for f in source_rgba, source_greyscale, source_non_utf, source_spaces:
157
- for source in Image.open(f), cv2.imread(str(f)), f:
158
- results = model(source, save=True, verbose=True, imgsz=32)
159
- assert len(results) == 1 # verify that an image was run
160
- f.unlink() # cleanup
161
-
162
-
163
- @pytest.mark.slow
164
- @pytest.mark.skipif(not ONLINE, reason="environment is offline")
165
- @pytest.mark.skipif(is_github_action_running(), reason="No auth https://github.com/JuanBindez/pytubefix/issues/166")
166
- def test_youtube():
167
- """Test YOLO model on a YouTube video stream, handling potential network-related errors."""
168
- model = YOLO(MODEL)
169
- try:
170
- model.predict("https://youtu.be/G17sBkb38XQ", imgsz=96, save=True)
171
- # Handle internet connection errors and 'urllib.error.HTTPError: HTTP Error 429: Too Many Requests'
172
- except (urllib.error.HTTPError, ConnectionError) as e:
173
- LOGGER.warning(f"WARNING: YouTube Test Error: {e}")
174
-
175
-
176
- @pytest.mark.skipif(not ONLINE, reason="environment is offline")
177
- @pytest.mark.skipif(not IS_TMP_WRITEABLE, reason="directory is not writeable")
178
- def test_track_stream():
179
- """
180
- Tests streaming tracking on a short 10 frame video using ByteTrack tracker and different GMC methods.
181
-
182
- Note imgsz=160 required for tracking for higher confidence and better matches.
183
- """
184
- video_url = "https://github.com/ultralytics/assets/releases/download/v0.0.0/decelera_portrait_min.mov"
185
- model = YOLO(MODEL)
186
- model.track(video_url, imgsz=160, tracker="bytetrack.yaml")
187
- model.track(video_url, imgsz=160, tracker="botsort.yaml", save_frames=True) # test frame saving also
188
-
189
- # Test Global Motion Compensation (GMC) methods
190
- for gmc in "orb", "sift", "ecc":
191
- with open(ROOT / "cfg/trackers/botsort.yaml", encoding="utf-8") as f:
192
- data = yaml.safe_load(f)
193
- tracker = TMP / f"botsort-{gmc}.yaml"
194
- data["gmc_method"] = gmc
195
- with open(tracker, "w", encoding="utf-8") as f:
196
- yaml.safe_dump(data, f)
197
- model.track(video_url, imgsz=160, tracker=tracker)
198
-
199
-
200
- def test_val():
201
- """Test the validation mode of the YOLO model."""
202
- YOLO(MODEL).val(data="coco8.yaml", imgsz=32, save_hybrid=True)
203
-
204
-
205
- def test_train_scratch():
206
- """Test training the YOLO model from scratch using the provided configuration."""
207
- model = YOLO(CFG)
208
- model.train(data="coco8.yaml", epochs=2, imgsz=32, cache="disk", batch=-1, close_mosaic=1, name="model")
209
- model(SOURCE)
210
-
211
-
212
- def test_train_pretrained():
213
- """Test training of the YOLO model starting from a pre-trained checkpoint."""
214
- model = YOLO(WEIGHTS_DIR / "yolo11n-seg.pt")
215
- model.train(data="coco8-seg.yaml", epochs=1, imgsz=32, cache="ram", copy_paste=0.5, mixup=0.5, name=0)
216
- model(SOURCE)
217
-
218
-
219
- def test_all_model_yamls():
220
- """Test YOLO model creation for all available YAML configurations in the `cfg/models` directory."""
221
- for m in (ROOT / "cfg" / "models").rglob("*.yaml"):
222
- if "rtdetr" in m.name:
223
- if TORCH_1_9: # torch<=1.8 issue - TypeError: __init__() got an unexpected keyword argument 'batch_first'
224
- _ = RTDETR(m.name)(SOURCE, imgsz=640) # must be 640
225
- else:
226
- YOLO(m.name)
227
-
228
-
229
- @pytest.mark.skipif(WINDOWS, reason="Windows slow CI export bug https://github.com/ultralytics/ultralytics/pull/16003")
230
- def test_workflow():
231
- """Test the complete workflow including training, validation, prediction, and exporting."""
232
- model = YOLO(MODEL)
233
- model.train(data="coco8.yaml", epochs=1, imgsz=32, optimizer="SGD")
234
- model.val(imgsz=32)
235
- model.predict(SOURCE, imgsz=32)
236
- model.export(format="torchscript") # WARNING: Windows slow CI export bug
237
-
238
-
239
- def test_predict_callback_and_setup():
240
- """Test callback functionality during YOLO prediction setup and execution."""
241
-
242
- def on_predict_batch_end(predictor):
243
- """Callback function that handles operations at the end of a prediction batch."""
244
- path, im0s, _ = predictor.batch
245
- im0s = im0s if isinstance(im0s, list) else [im0s]
246
- bs = [predictor.dataset.bs for _ in range(len(path))]
247
- predictor.results = zip(predictor.results, im0s, bs) # results is List[batch_size]
248
-
249
- model = YOLO(MODEL)
250
- model.add_callback("on_predict_batch_end", on_predict_batch_end)
251
-
252
- dataset = load_inference_source(source=SOURCE)
253
- bs = dataset.bs # noqa access predictor properties
254
- results = model.predict(dataset, stream=True, imgsz=160) # source already setup
255
- for r, im0, bs in results:
256
- print("test_callback", im0.shape)
257
- print("test_callback", bs)
258
- boxes = r.boxes # Boxes object for bbox outputs
259
- print(boxes)
260
-
261
-
262
- @pytest.mark.parametrize("model", MODELS)
263
- def test_results(model):
264
- """Ensure YOLO model predictions can be processed and printed in various formats."""
265
- results = YOLO(WEIGHTS_DIR / model)([SOURCE, SOURCE], imgsz=160)
266
- for r in results:
267
- r = r.cpu().numpy()
268
- print(r, len(r), r.path) # print numpy attributes
269
- r = r.to(device="cpu", dtype=torch.float32)
270
- r.save_txt(txt_file=TMP / "runs/tests/label.txt", save_conf=True)
271
- r.save_crop(save_dir=TMP / "runs/tests/crops/")
272
- r.to_json(normalize=True)
273
- r.to_df(decimals=3)
274
- r.to_csv()
275
- r.to_xml()
276
- r.plot(pil=True)
277
- r.plot(conf=True, boxes=True)
278
- print(r, len(r), r.path) # print after methods
279
-
280
-
281
- def test_labels_and_crops():
282
- """Test output from prediction args for saving YOLO detection labels and crops; ensures accurate saving."""
283
- imgs = [SOURCE, ASSETS / "zidane.jpg"]
284
- results = YOLO(WEIGHTS_DIR / "yolo11n.pt")(imgs, imgsz=160, save_txt=True, save_crop=True)
285
- save_path = Path(results[0].save_dir)
286
- for r in results:
287
- im_name = Path(r.path).stem
288
- cls_idxs = r.boxes.cls.int().tolist()
289
- # Check correct detections
290
- assert cls_idxs == ([0, 7, 0, 0] if r.path.endswith("bus.jpg") else [0, 0, 0]) # bus.jpg and zidane.jpg classes
291
- # Check label path
292
- labels = save_path / f"labels/{im_name}.txt"
293
- assert labels.exists()
294
- # Check detections match label count
295
- assert len(r.boxes.data) == len([line for line in labels.read_text().splitlines() if line])
296
- # Check crops path and files
297
- crop_dirs = list((save_path / "crops").iterdir())
298
- crop_files = [f for p in crop_dirs for f in p.glob("*")]
299
- # Crop directories match detections
300
- assert all(r.names.get(c) in {d.name for d in crop_dirs} for c in cls_idxs)
301
- # Same number of crops as detections
302
- assert len([f for f in crop_files if im_name in f.name]) == len(r.boxes.data)
303
-
304
-
305
- @pytest.mark.skipif(not ONLINE, reason="environment is offline")
306
- def test_data_utils():
307
- """Test utility functions in ultralytics/data/utils.py, including dataset stats and auto-splitting."""
308
- from ultralytics.data.utils import HUBDatasetStats, autosplit
309
- from ultralytics.utils.downloads import zip_directory
310
-
311
- # from ultralytics.utils.files import WorkingDirectory
312
- # with WorkingDirectory(ROOT.parent / 'tests'):
313
-
314
- for task in TASKS:
315
- file = Path(TASK2DATA[task]).with_suffix(".zip") # i.e. coco8.zip
316
- download(f"https://github.com/ultralytics/hub/raw/main/example_datasets/{file}", unzip=False, dir=TMP)
317
- stats = HUBDatasetStats(TMP / file, task=task)
318
- stats.get_json(save=True)
319
- stats.process_images()
320
-
321
- autosplit(TMP / "coco8")
322
- zip_directory(TMP / "coco8/images/val") # zip
323
-
324
-
325
- @pytest.mark.skipif(not ONLINE, reason="environment is offline")
326
- def test_data_converter():
327
- """Test dataset conversion functions from COCO to YOLO format and class mappings."""
328
- from ultralytics.data.converter import coco80_to_coco91_class, convert_coco
329
-
330
- file = "instances_val2017.json"
331
- download(f"https://github.com/ultralytics/assets/releases/download/v0.0.0/{file}", dir=TMP)
332
- convert_coco(labels_dir=TMP, save_dir=TMP / "yolo_labels", use_segments=True, use_keypoints=False, cls91to80=True)
333
- coco80_to_coco91_class()
334
-
335
-
336
- def test_data_annotator():
337
- """Automatically annotate data using specified detection and segmentation models."""
338
- from ultralytics.data.annotator import auto_annotate
339
-
340
- auto_annotate(
341
- ASSETS,
342
- det_model=WEIGHTS_DIR / "yolo11n.pt",
343
- sam_model=WEIGHTS_DIR / "mobile_sam.pt",
344
- output_dir=TMP / "auto_annotate_labels",
345
- )
346
-
347
-
348
- def test_events():
349
- """Test event sending functionality."""
350
- from ultralytics.hub.utils import Events
351
-
352
- events = Events()
353
- events.enabled = True
354
- cfg = copy(DEFAULT_CFG) # does not require deepcopy
355
- cfg.mode = "test"
356
- events(cfg)
357
-
358
-
359
- def test_cfg_init():
360
- """Test configuration initialization utilities from the 'ultralytics.cfg' module."""
361
- from ultralytics.cfg import check_dict_alignment, copy_default_cfg, smart_value
362
-
363
- with contextlib.suppress(SyntaxError):
364
- check_dict_alignment({"a": 1}, {"b": 2})
365
- copy_default_cfg()
366
- (Path.cwd() / DEFAULT_CFG_PATH.name.replace(".yaml", "_copy.yaml")).unlink(missing_ok=False)
367
- [smart_value(x) for x in ["none", "true", "false"]]
368
-
369
-
370
- def test_utils_init():
371
- """Test initialization utilities in the Ultralytics library."""
372
- from ultralytics.utils import get_git_branch, get_git_origin_url, get_ubuntu_version, is_github_action_running
373
-
374
- get_ubuntu_version()
375
- is_github_action_running()
376
- get_git_origin_url()
377
- get_git_branch()
378
-
379
-
380
- def test_utils_checks():
381
- """Test various utility checks for filenames, git status, requirements, image sizes, and versions."""
382
- checks.check_yolov5u_filename("yolov5n.pt")
383
- checks.git_describe(ROOT)
384
- checks.check_requirements() # check requirements.txt
385
- checks.check_imgsz([600, 600], max_dim=1)
386
- checks.check_imshow(warn=True)
387
- checks.check_version("ultralytics", "8.0.0")
388
- checks.print_args()
389
-
390
-
391
- @pytest.mark.skipif(WINDOWS, reason="Windows profiling is extremely slow (cause unknown)")
392
- def test_utils_benchmarks():
393
- """Benchmark model performance using 'ProfileModels' from 'ultralytics.utils.benchmarks'."""
394
- from ultralytics.utils.benchmarks import ProfileModels
395
-
396
- ProfileModels(["yolo11n.yaml"], imgsz=32, min_time=1, num_timed_runs=3, num_warmup_runs=1).profile()
397
-
398
-
399
- def test_utils_torchutils():
400
- """Test Torch utility functions including profiling and FLOP calculations."""
401
- from ultralytics.nn.modules.conv import Conv
402
- from ultralytics.utils.torch_utils import get_flops_with_torch_profiler, profile, time_sync
403
-
404
- x = torch.randn(1, 64, 20, 20)
405
- m = Conv(64, 64, k=1, s=2)
406
-
407
- profile(x, [m], n=3)
408
- get_flops_with_torch_profiler(m)
409
- time_sync()
410
-
411
-
412
- def test_utils_ops():
413
- """Test utility operations functions for coordinate transformation and normalization."""
414
- from ultralytics.utils.ops import (
415
- ltwh2xywh,
416
- ltwh2xyxy,
417
- make_divisible,
418
- xywh2ltwh,
419
- xywh2xyxy,
420
- xywhn2xyxy,
421
- xywhr2xyxyxyxy,
422
- xyxy2ltwh,
423
- xyxy2xywh,
424
- xyxy2xywhn,
425
- xyxyxyxy2xywhr,
426
- )
427
-
428
- make_divisible(17, torch.tensor([8]))
429
-
430
- boxes = torch.rand(10, 4) # xywh
431
- torch.allclose(boxes, xyxy2xywh(xywh2xyxy(boxes)))
432
- torch.allclose(boxes, xyxy2xywhn(xywhn2xyxy(boxes)))
433
- torch.allclose(boxes, ltwh2xywh(xywh2ltwh(boxes)))
434
- torch.allclose(boxes, xyxy2ltwh(ltwh2xyxy(boxes)))
435
-
436
- boxes = torch.rand(10, 5) # xywhr for OBB
437
- boxes[:, 4] = torch.randn(10) * 30
438
- torch.allclose(boxes, xyxyxyxy2xywhr(xywhr2xyxyxyxy(boxes)), rtol=1e-3)
439
-
440
-
441
- def test_utils_files():
442
- """Test file handling utilities including file age, date, and paths with spaces."""
443
- from ultralytics.utils.files import file_age, file_date, get_latest_run, spaces_in_path
444
-
445
- file_age(SOURCE)
446
- file_date(SOURCE)
447
- get_latest_run(ROOT / "runs")
448
-
449
- path = TMP / "path/with spaces"
450
- path.mkdir(parents=True, exist_ok=True)
451
- with spaces_in_path(path) as new_path:
452
- print(new_path)
453
-
454
-
455
- @pytest.mark.slow
456
- def test_utils_patches_torch_save():
457
- """Test torch_save backoff when _torch_save raises RuntimeError to ensure robustness."""
458
- from unittest.mock import MagicMock, patch
459
-
460
- from ultralytics.utils.patches import torch_save
461
-
462
- mock = MagicMock(side_effect=RuntimeError)
463
-
464
- with patch("ultralytics.utils.patches._torch_save", new=mock):
465
- with pytest.raises(RuntimeError):
466
- torch_save(torch.zeros(1), TMP / "test.pt")
467
-
468
- assert mock.call_count == 4, "torch_save was not attempted the expected number of times"
469
-
470
-
471
- def test_nn_modules_conv():
472
- """Test Convolutional Neural Network modules including CBAM, Conv2, and ConvTranspose."""
473
- from ultralytics.nn.modules.conv import CBAM, Conv2, ConvTranspose, DWConvTranspose2d, Focus
474
-
475
- c1, c2 = 8, 16 # input and output channels
476
- x = torch.zeros(4, c1, 10, 10) # BCHW
477
-
478
- # Run all modules not otherwise covered in tests
479
- DWConvTranspose2d(c1, c2)(x)
480
- ConvTranspose(c1, c2)(x)
481
- Focus(c1, c2)(x)
482
- CBAM(c1)(x)
483
-
484
- # Fuse ops
485
- m = Conv2(c1, c2)
486
- m.fuse_convs()
487
- m(x)
488
-
489
-
490
- def test_nn_modules_block():
491
- """Test various blocks in neural network modules including C1, C3TR, BottleneckCSP, C3Ghost, and C3x."""
492
- from ultralytics.nn.modules.block import C1, C3TR, BottleneckCSP, C3Ghost, C3x
493
-
494
- c1, c2 = 8, 16 # input and output channels
495
- x = torch.zeros(4, c1, 10, 10) # BCHW
496
-
497
- # Run all modules not otherwise covered in tests
498
- C1(c1, c2)(x)
499
- C3x(c1, c2)(x)
500
- C3TR(c1, c2)(x)
501
- C3Ghost(c1, c2)(x)
502
- BottleneckCSP(c1, c2)(x)
503
-
504
-
505
- @pytest.mark.skipif(not ONLINE, reason="environment is offline")
506
- def test_hub():
507
- """Test Ultralytics HUB functionalities (e.g. export formats, logout)."""
508
- from ultralytics.hub import export_fmts_hub, logout
509
- from ultralytics.hub.utils import smart_request
510
-
511
- export_fmts_hub()
512
- logout()
513
- smart_request("GET", "https://github.com", progress=True)
514
-
515
-
516
- @pytest.fixture
517
- def image():
518
- """Load and return an image from a predefined source using OpenCV."""
519
- return cv2.imread(str(SOURCE))
520
-
521
-
522
- @pytest.mark.parametrize(
523
- "auto_augment, erasing, force_color_jitter",
524
- [
525
- (None, 0.0, False),
526
- ("randaugment", 0.5, True),
527
- ("augmix", 0.2, False),
528
- ("autoaugment", 0.0, True),
529
- ],
530
- )
531
- def test_classify_transforms_train(image, auto_augment, erasing, force_color_jitter):
532
- """Tests classification transforms during training with various augmentations to ensure proper functionality."""
533
- from ultralytics.data.augment import classify_augmentations
534
-
535
- transform = classify_augmentations(
536
- size=224,
537
- mean=(0.5, 0.5, 0.5),
538
- std=(0.5, 0.5, 0.5),
539
- scale=(0.08, 1.0),
540
- ratio=(3.0 / 4.0, 4.0 / 3.0),
541
- hflip=0.5,
542
- vflip=0.5,
543
- auto_augment=auto_augment,
544
- hsv_h=0.015,
545
- hsv_s=0.4,
546
- hsv_v=0.4,
547
- force_color_jitter=force_color_jitter,
548
- erasing=erasing,
549
- )
550
-
551
- transformed_image = transform(Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)))
552
-
553
- assert transformed_image.shape == (3, 224, 224)
554
- assert torch.is_tensor(transformed_image)
555
- assert transformed_image.dtype == torch.float32
556
-
557
-
558
- @pytest.mark.slow
559
- @pytest.mark.skipif(not ONLINE, reason="environment is offline")
560
- def test_model_tune():
561
- """Tune YOLO model for performance improvement."""
562
- YOLO("yolo11n-pose.pt").tune(data="coco8-pose.yaml", plots=False, imgsz=32, epochs=1, iterations=2, device="cpu")
563
- YOLO("yolo11n-cls.pt").tune(data="imagenet10", plots=False, imgsz=32, epochs=1, iterations=2, device="cpu")
564
-
565
-
566
- def test_model_embeddings():
567
- """Test YOLO model embeddings."""
568
- model_detect = YOLO(MODEL)
569
- model_segment = YOLO(WEIGHTS_DIR / "yolo11n-seg.pt")
570
-
571
- for batch in [SOURCE], [SOURCE, SOURCE]: # test batch size 1 and 2
572
- assert len(model_detect.embed(source=batch, imgsz=32)) == len(batch)
573
- assert len(model_segment.embed(source=batch, imgsz=32)) == len(batch)
574
-
575
-
576
- @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="YOLOWorld with CLIP is not supported in Python 3.12")
577
- def test_yolo_world():
578
- """Tests YOLO world models with CLIP support, including detection and training scenarios."""
579
- model = YOLO(WEIGHTS_DIR / "yolov8s-world.pt") # no YOLO11n-world model yet
580
- model.set_classes(["tree", "window"])
581
- model(SOURCE, conf=0.01)
582
-
583
- model = YOLO(WEIGHTS_DIR / "yolov8s-worldv2.pt") # no YOLO11n-world model yet
584
- # Training from a pretrained model. Eval is included at the final stage of training.
585
- # Use dota8.yaml which has fewer categories to reduce the inference time of CLIP model
586
- model.train(
587
- data="dota8.yaml",
588
- epochs=1,
589
- imgsz=32,
590
- cache="disk",
591
- close_mosaic=1,
592
- )
593
-
594
- # test WorWorldTrainerFromScratch
595
- from ultralytics.models.yolo.world.train_world import WorldTrainerFromScratch
596
-
597
- model = YOLO("yolov8s-worldv2.yaml") # no YOLO11n-world model yet
598
- model.train(
599
- data={"train": {"yolo_data": ["dota8.yaml"]}, "val": {"yolo_data": ["dota8.yaml"]}},
600
- epochs=1,
601
- imgsz=32,
602
- cache="disk",
603
- close_mosaic=1,
604
- trainer=WorldTrainerFromScratch,
605
- )
606
-
607
-
608
- def test_yolov10():
609
- """Test YOLOv10 model training, validation, and prediction steps with minimal configurations."""
610
- model = YOLO("yolov10n.yaml")
611
- # train/val/predict
612
- model.train(data="coco8.yaml", epochs=1, imgsz=32, close_mosaic=1, cache="disk")
613
- model.val(data="coco8.yaml", imgsz=32)
614
- model.predict(imgsz=32, save_txt=True, save_crop=True, augment=True)
615
- model(SOURCE)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/test_solutions.py DELETED
@@ -1,94 +0,0 @@
1
- # Ultralytics πŸš€ AGPL-3.0 License - https://ultralytics.com/license
2
-
3
- import cv2
4
- import pytest
5
-
6
- from tests import TMP
7
- from ultralytics import YOLO, solutions
8
- from ultralytics.utils import ASSETS_URL, WEIGHTS_DIR
9
- from ultralytics.utils.downloads import safe_download
10
-
11
- DEMO_VIDEO = "solutions_ci_demo.mp4"
12
- POSE_VIDEO = "solution_ci_pose_demo.mp4"
13
-
14
-
15
- @pytest.mark.slow
16
- def test_major_solutions():
17
- """Test the object counting, heatmap, speed estimation, trackzone and queue management solution."""
18
- safe_download(url=f"{ASSETS_URL}/{DEMO_VIDEO}", dir=TMP)
19
- cap = cv2.VideoCapture(str(TMP / DEMO_VIDEO))
20
- assert cap.isOpened(), "Error reading video file"
21
- region_points = [(20, 400), (1080, 400), (1080, 360), (20, 360)]
22
- counter = solutions.ObjectCounter(region=region_points, model="yolo11n.pt", show=False) # Test object counter
23
- heatmap = solutions.Heatmap(colormap=cv2.COLORMAP_PARULA, model="yolo11n.pt", show=False) # Test heatmaps
24
- heatmap_count = solutions.Heatmap(
25
- colormap=cv2.COLORMAP_PARULA, model="yolo11n.pt", show=False, region=region_points
26
- ) # Test heatmaps with object counting
27
- speed = solutions.SpeedEstimator(region=region_points, model="yolo11n.pt", show=False) # Test queue manager
28
- queue = solutions.QueueManager(region=region_points, model="yolo11n.pt", show=False) # Test speed estimation
29
- line_analytics = solutions.Analytics(analytics_type="line", model="yolo11n.pt", show=False) # line analytics
30
- pie_analytics = solutions.Analytics(analytics_type="pie", model="yolo11n.pt", show=False) # line analytics
31
- bar_analytics = solutions.Analytics(analytics_type="bar", model="yolo11n.pt", show=False) # line analytics
32
- area_analytics = solutions.Analytics(analytics_type="area", model="yolo11n.pt", show=False) # line analytics
33
- trackzone = solutions.TrackZone(region=region_points, model="yolo11n.pt", show=False) # Test trackzone
34
- frame_count = 0 # Required for analytics
35
- while cap.isOpened():
36
- success, im0 = cap.read()
37
- if not success:
38
- break
39
- frame_count += 1
40
- original_im0 = im0.copy()
41
- _ = counter.count(original_im0.copy())
42
- _ = heatmap.generate_heatmap(original_im0.copy())
43
- _ = heatmap_count.generate_heatmap(original_im0.copy())
44
- _ = speed.estimate_speed(original_im0.copy())
45
- _ = queue.process_queue(original_im0.copy())
46
- _ = line_analytics.process_data(original_im0.copy(), frame_count)
47
- _ = pie_analytics.process_data(original_im0.copy(), frame_count)
48
- _ = bar_analytics.process_data(original_im0.copy(), frame_count)
49
- _ = area_analytics.process_data(original_im0.copy(), frame_count)
50
- _ = trackzone.trackzone(original_im0.copy())
51
- cap.release()
52
-
53
- # Test workouts monitoring
54
- safe_download(url=f"{ASSETS_URL}/{POSE_VIDEO}", dir=TMP)
55
- cap = cv2.VideoCapture(str(TMP / POSE_VIDEO))
56
- assert cap.isOpened(), "Error reading video file"
57
- gym = solutions.AIGym(kpts=[5, 11, 13], show=False)
58
- while cap.isOpened():
59
- success, im0 = cap.read()
60
- if not success:
61
- break
62
- _ = gym.monitor(im0)
63
- cap.release()
64
-
65
-
66
- @pytest.mark.slow
67
- def test_instance_segmentation():
68
- """Test the instance segmentation solution."""
69
- from ultralytics.utils.plotting import Annotator, colors
70
-
71
- model = YOLO(WEIGHTS_DIR / "yolo11n-seg.pt")
72
- names = model.names
73
- cap = cv2.VideoCapture(TMP / DEMO_VIDEO)
74
- assert cap.isOpened(), "Error reading video file"
75
- while cap.isOpened():
76
- success, im0 = cap.read()
77
- if not success:
78
- break
79
- results = model.predict(im0)
80
- annotator = Annotator(im0, line_width=2)
81
- if results[0].masks is not None:
82
- clss = results[0].boxes.cls.cpu().tolist()
83
- masks = results[0].masks.xy
84
- for mask, cls in zip(masks, clss):
85
- color = colors(int(cls), True)
86
- annotator.seg_bbox(mask=mask, mask_color=color, label=names[int(cls)])
87
- cap.release()
88
- cv2.destroyAllWindows()
89
-
90
-
91
- @pytest.mark.slow
92
- def test_streamlit_predict():
93
- """Test streamlit predict live inference solution."""
94
- solutions.Inference().inference()