Skip to content

Commit

Permalink
ultralytics 8.1.1 Docs, Solutions and Export updates (ultralytics#7545
Browse files Browse the repository at this point in the history
)

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>
  • Loading branch information
5 people authored and gkinman committed May 30, 2024
1 parent 822e1c8 commit f2ffaf1
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 26 deletions.
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile-python
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 7 additions & 0 deletions docs/overrides/stylesheets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
4 changes: 1 addition & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
]

Expand Down
15 changes: 15 additions & 0 deletions tests/test_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion ultralytics/__init__.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 1 addition & 0 deletions ultralytics/engine/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ def export_coreml(self, prefix=colorstr("CoreML:")):
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)
Expand Down
34 changes: 19 additions & 15 deletions ultralytics/solutions/object_counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,25 +182,29 @@ def extract_and_process_tracks(self, tracks):
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}"
Expand Down
8 changes: 5 additions & 3 deletions ultralytics/utils/benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
13 changes: 11 additions & 2 deletions ultralytics/utils/patches.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -61,7 +62,8 @@ def imshow(winname: str, mat: np.ndarray):

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.
Expand All @@ -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

0 comments on commit f2ffaf1

Please sign in to comment.