`ultralytics 8.1.1` Docs, Solutions and Export updates (#7545)

Co-authored-by: Sergiu Waxmann <47978446+sergiuwaxmann@users.noreply.github.com>
Co-authored-by: Vivek Malvi <malvivivek8198@gmail.com>
Co-authored-by: UltralyticsAssistant <web@ultralytics.com>
Co-authored-by: psaxton <psaxton+github.com@gmail.com>
pull/7546/head v8.1.1
Glenn Jocher 11 months ago committed by GitHub
parent 30185e0d4c
commit 83165ffe9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      docker/Dockerfile
  2. 2
      docker/Dockerfile-python
  3. 7
      docs/overrides/stylesheets/style.css
  4. 4
      pyproject.toml
  5. 15
      tests/test_python.py
  6. 2
      ultralytics/__init__.py
  7. 1
      ultralytics/engine/exporter.py
  8. 34
      ultralytics/solutions/object_counter.py
  9. 8
      ultralytics/utils/benchmarks.py
  10. 13
      ultralytics/utils/patches.py

@ -34,7 +34,7 @@ RUN pip install --no-cache -e ".[export]" albumentations comet pycocotools lance
RUN yolo export model=tmp/yolov8n.pt format=edgetpu imgsz=32
RUN yolo export model=tmp/yolov8n.pt format=ncnn imgsz=32
# Requires <= Python 3.10, bug with paddlepaddle==2.5.0 https://github.com/PaddlePaddle/X2Paddle/issues/991
RUN pip install --no-cache paddlepaddle==2.4.2 x2paddle
RUN pip install --no-cache paddlepaddle>=2.6.0 x2paddle
# Fix error: `np.bool` was a deprecated alias for the builtin `bool` segmentation error in Tests
RUN pip install --no-cache numpy==1.23.5
# Remove exported models

@ -32,7 +32,7 @@ RUN pip install --no-cache -e ".[export]" lancedb --extra-index-url https://down
RUN yolo export model=tmp/yolov8n.pt format=edgetpu imgsz=32
RUN yolo export model=tmp/yolov8n.pt format=ncnn imgsz=32
# Requires <= Python 3.10, bug with paddlepaddle==2.5.0 https://github.com/PaddlePaddle/X2Paddle/issues/991
RUN pip install --no-cache paddlepaddle==2.4.2 x2paddle
RUN pip install --no-cache paddlepaddle>=2.6.0 x2paddle
# Remove exported models
RUN rm -rf tmp

@ -48,3 +48,10 @@ div.highlight {
.md-header .md-select:hover .md-select__inner {
max-height: 75vh;
}
/* Update the background of the banner (same as the one on the Ultralytics website) */
.md-banner {
background-image: url(https://assets-global.website-files.com/646dd1f1a3703e451ba81ecc/659fc4f4163e480e7ec280d0_banner.webp);
background-size: cover;
background-position: center;
}

@ -98,11 +98,9 @@ dev = [
]
export = [
"onnx>=1.12.0", # ONNX export
"coremltools>=7.0", # CoreML export
"coremltools>=7.0; platform_system != 'Windows'", # CoreML only supported on macOS and Linux
"openvino-dev>=2023.0", # OpenVINO export
"tensorflow<=2.13.1", # TF bug https://github.com/ultralytics/ultralytics/issues/5161
"jax<=0.4.21", # tensorflowjs bug https://github.com/google/jax/issues/18978
"jaxlib<=0.4.21", # tensorflowjs bug https://github.com/google/jax/issues/18978
"tensorflowjs>=3.9.0", # TF.js export, automatically installs tensorflow
]

@ -463,6 +463,21 @@ def test_utils_files():
print(new_path)
@pytest.mark.slow
def test_utils_patches_torch_save():
"""Test torch_save backoff when _torch_save throws RuntimeError."""
from unittest.mock import patch, MagicMock
from ultralytics.utils.patches import torch_save
mock = MagicMock(side_effect=RuntimeError)
with patch('ultralytics.utils.patches._torch_save', new=mock):
with pytest.raises(RuntimeError):
torch_save(torch.zeros(1), TMP / 'test.pt')
assert mock.call_count == 4, "torch_save was not attempted the expected number of times"
def test_nn_modules_conv():
"""Test Convolutional Neural Network modules."""
from ultralytics.nn.modules.conv import CBAM, Conv2, ConvTranspose, DWConvTranspose2d, Focus

@ -1,6 +1,6 @@
# Ultralytics YOLO 🚀, AGPL-3.0 license
__version__ = "8.1.0"
__version__ = "8.1.1"
from ultralytics.data.explorer.explorer import Explorer
from ultralytics.models import RTDETR, SAM, YOLO

@ -555,6 +555,7 @@ class Exporter:
import coremltools as ct # noqa
LOGGER.info(f"\n{prefix} starting export with coremltools {ct.__version__}...")
assert not WINDOWS, "CoreML export is not supported on Windows, please run on macOS or Linux."
f = self.file.with_suffix(".mlmodel" if mlmodel else ".mlpackage")
if f.is_dir():
shutil.rmtree(f)

@ -182,25 +182,29 @@ class ObjectCounter:
track_line, color=self.track_color, track_thickness=self.track_thickness
)
prev_position = self.track_history[track_id][-2] if len(self.track_history[track_id]) > 1 else None
# Count objects
if len(self.reg_pts) == 4:
if self.counting_region.contains(Point(track_line[-1])):
if track_id not in self.counting_list:
self.counting_list.append(track_id)
if box[0] < self.counting_region.centroid.x:
self.out_counts += 1
else:
self.in_counts += 1
if prev_position is not None:
if self.counting_region.contains(Point(track_line[-1])):
if track_id not in self.counting_list:
self.counting_list.append(track_id)
if (box[0] - prev_position[0]) * (self.counting_region.centroid.x - prev_position[0]) > 0:
self.in_counts += 1
else:
self.out_counts += 1
elif len(self.reg_pts) == 2:
distance = Point(track_line[-1]).distance(self.counting_region)
if distance < self.line_dist_thresh:
if track_id not in self.counting_list:
self.counting_list.append(track_id)
if box[0] < self.counting_region.centroid.x:
self.out_counts += 1
else:
self.in_counts += 1
if prev_position is not None:
distance = Point(track_line[-1]).distance(self.counting_region)
if distance < self.line_dist_thresh:
if track_id not in self.counting_list:
self.counting_list.append(track_id)
if (box[0] - prev_position[0]) * (self.counting_region.centroid.x - prev_position[0]) > 0:
self.in_counts += 1
else:
self.out_counts += 1
incount_label = "In Count : " + f"{self.in_counts}"
outcount_label = "OutCount : " + f"{self.out_counts}"

@ -85,10 +85,12 @@ def benchmark(
emoji, filename = "", None # export defaults
try:
assert i != 9 or LINUX, "Edge TPU export only supported on Linux"
if i == 10:
if i == 5:
assert MACOS or LINUX, "CoreML export only supported on macOS and Linux"
elif i == 10:
assert MACOS or LINUX, "TF.js export only supported on macOS and Linux"
elif i == 11:
assert sys.version_info < (3, 11), "PaddlePaddle export only supported on Python<=3.10"
# elif i == 11:
# assert sys.version_info < (3, 11), "PaddlePaddle export only supported on Python<=3.10"
if "cpu" in device.type:
assert cpu, "inference not supported on CPU"
if "cuda" in device.type:

@ -1,6 +1,7 @@
# Ultralytics YOLO 🚀, AGPL-3.0 license
"""Monkey patches to update/extend functionality of existing functions."""
import time
from pathlib import Path
import cv2
@ -61,7 +62,8 @@ _torch_save = torch.save # copy to avoid recursion errors
def torch_save(*args, **kwargs):
"""
Use dill (if exists) to serialize the lambda functions where pickle does not do this.
Use dill (if exists) to serialize the lambda functions where pickle does not do this. Also adds 3 retries with
exponential standoff in case of save failure to improve robustness to transient issues.
Args:
*args (tuple): Positional arguments to pass to torch.save.
@ -74,4 +76,11 @@ def torch_save(*args, **kwargs):
if "pickle_module" not in kwargs:
kwargs["pickle_module"] = pickle # noqa
return _torch_save(*args, **kwargs)
for i in range(4): # 3 retries
try:
return _torch_save(*args, **kwargs)
except RuntimeError: # unable to save, possibly waiting for device to flush or anti-virus to finish scanning
if i == 3:
raise
time.sleep((2**i) / 2) # exponential standoff 0.5s, 1.0s, 2.0s

Loading…
Cancel
Save