diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 50bd6057..b457baf3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -102,11 +102,11 @@ jobs: python-version: ["3.11"] model: [yolo11n] steps: - - uses: astral-sh/setup-uv@v5 - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + - uses: astral-sh/setup-uv@v5 - name: Install requirements shell: bash # for Windows compatibility run: | diff --git a/tests/conftest.py b/tests/conftest.py index 7b0539b4..eda01add 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -74,10 +74,10 @@ def pytest_terminal_summary(terminalreporter, exitstatus, config): # Remove files models = [path for x in ["*.onnx", "*.torchscript"] for path in WEIGHTS_DIR.rglob(x)] - for file in ["bus.jpg", "yolo11n.onnx", "yolo11n.torchscript"] + models: + for file in ["decelera_portrait_min.mov", "bus.jpg", "yolo11n.onnx", "yolo11n.torchscript"] + models: Path(file).unlink(missing_ok=True) # Remove directories models = [path for x in ["*.mlpackage", "*_openvino_model"] for path in WEIGHTS_DIR.rglob(x)] - for directory in [TMP.parents[1] / ".pytest_cache", TMP] + models: + for directory in [WEIGHTS_DIR / "path with spaces", TMP.parents[1] / ".pytest_cache", TMP] + models: shutil.rmtree(directory, ignore_errors=True) diff --git a/tests/test_cli.py b/tests/test_cli.py index 05e06bd7..8c102ed9 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -59,7 +59,8 @@ def test_rtdetr(task="detect", model="yolov8n-rtdetr.yaml", data="coco8.yaml"): run(f"yolo train {task} model={model} data={data} --imgsz= 160 epochs =1, cache = disk fraction=0.25") run(f"yolo predict {task} model={model} source={ASSETS / 'bus.jpg'} imgsz=160 save save_crop save_txt") if TORCH_1_9: - run(f"yolo predict {task} model='rtdetr-l.pt' source={ASSETS / 'bus.jpg'} imgsz=160 save save_crop save_txt") + weights = WEIGHTS_DIR / "rtdetr-l.pt" + run(f"yolo predict {task} model={weights} source={ASSETS / 'bus.jpg'} imgsz=160 save save_crop save_txt") @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="MobileSAM with CLIP is not supported in Python 3.12") diff --git a/tests/test_python.py b/tests/test_python.py index 3d497050..c2c25392 100644 --- a/tests/test_python.py +++ b/tests/test_python.py @@ -576,11 +576,11 @@ def test_model_embeddings(): @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="YOLOWorld with CLIP is not supported in Python 3.12") def test_yolo_world(): """Tests YOLO world models with CLIP support, including detection and training scenarios.""" - model = YOLO("yolov8s-world.pt") # no YOLO11n-world model yet + model = YOLO(WEIGHTS_DIR / "yolov8s-world.pt") # no YOLO11n-world model yet model.set_classes(["tree", "window"]) model(SOURCE, conf=0.01) - model = YOLO("yolov8s-worldv2.pt") # no YOLO11n-world model yet + model = YOLO(WEIGHTS_DIR / "yolov8s-worldv2.pt") # no YOLO11n-world model yet # Training from a pretrained model. Eval is included at the final stage of training. # Use dota8.yaml which has fewer categories to reduce the inference time of CLIP model model.train( diff --git a/tests/test_solutions.py b/tests/test_solutions.py index 730ba95d..e35c41b2 100644 --- a/tests/test_solutions.py +++ b/tests/test_solutions.py @@ -3,18 +3,20 @@ import cv2 import pytest +from tests import TMP from ultralytics import YOLO, solutions +from ultralytics.utils import ASSETS_URL, WEIGHTS_DIR from ultralytics.utils.downloads import safe_download -MAJOR_SOLUTIONS_DEMO = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4" -WORKOUTS_SOLUTION_DEMO = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solution_ci_pose_demo.mp4" +DEMO_VIDEO = "solutions_ci_demo.mp4" +POSE_VIDEO = "solution_ci_pose_demo.mp4" @pytest.mark.slow def test_major_solutions(): """Test the object counting, heatmap, speed estimation and queue management solution.""" - safe_download(url=MAJOR_SOLUTIONS_DEMO) - cap = cv2.VideoCapture("solutions_ci_demo.mp4") + safe_download(url=f"{ASSETS_URL}/{DEMO_VIDEO}", dir=TMP) + cap = cv2.VideoCapture(str(TMP / DEMO_VIDEO)) assert cap.isOpened(), "Error reading video file" region_points = [(20, 400), (1080, 400), (1080, 360), (20, 360)] counter = solutions.ObjectCounter(region=region_points, model="yolo11n.pt", show=False) # Test object counter @@ -42,8 +44,8 @@ def test_major_solutions(): cap.release() # Test workouts monitoring - safe_download(url=WORKOUTS_SOLUTION_DEMO) - cap1 = cv2.VideoCapture("solution_ci_pose_demo.mp4") + safe_download(url=f"{ASSETS_URL}/{POSE_VIDEO}", dir=TMP) + cap1 = cv2.VideoCapture(str(TMP / POSE_VIDEO)) assert cap1.isOpened(), "Error reading video file" gym = solutions.AIGym(line_width=2, kpts=[5, 11, 13], show=False) while cap1.isOpened(): @@ -59,9 +61,9 @@ def test_instance_segmentation(): """Test the instance segmentation solution.""" from ultralytics.utils.plotting import Annotator, colors - model = YOLO("yolo11n-seg.pt") + model = YOLO(WEIGHTS_DIR / "yolo11n-seg.pt") names = model.names - cap = cv2.VideoCapture("solutions_ci_demo.mp4") + cap = cv2.VideoCapture(TMP / DEMO_VIDEO) assert cap.isOpened(), "Error reading video file" while cap.isOpened(): success, im0 = cap.read() diff --git a/ultralytics/nn/autobackend.py b/ultralytics/nn/autobackend.py index a2a7816a..9edfa11d 100644 --- a/ultralytics/nn/autobackend.py +++ b/ultralytics/nn/autobackend.py @@ -192,14 +192,14 @@ class AutoBackend(nn.Module): check_requirements("numpy==1.23.5") import onnxruntime - providers = onnxruntime.get_available_providers() - if not cuda and "CUDAExecutionProvider" in providers: - providers.remove("CUDAExecutionProvider") - elif cuda and "CUDAExecutionProvider" not in providers: - LOGGER.warning("WARNING ⚠️ Failed to start ONNX Runtime session with CUDA. Falling back to CPU...") + providers = ["CPUExecutionProvider"] + if cuda and "CUDAExecutionProvider" in onnxruntime.get_available_providers(): + providers.insert(0, "CUDAExecutionProvider") + elif cuda: # Only log warning if CUDA was requested but unavailable + LOGGER.warning("WARNING ⚠️ Failed to start ONNX Runtime with CUDA. Using CPU...") device = torch.device("cpu") cuda = False - LOGGER.info(f"Preferring ONNX Runtime {providers[0]}") + LOGGER.info(f"Using ONNX Runtime {providers[0]}") if onnx: session = onnxruntime.InferenceSession(w, providers=providers) else: