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.

Files changed (178) hide show
  1. {ultralytics-8.0.194/ultralytics.egg-info → ultralytics-8.0.196}/PKG-INFO +1 -1
  2. {ultralytics-8.0.194 → ultralytics-8.0.196}/setup.cfg +9 -0
  3. {ultralytics-8.0.194 → ultralytics-8.0.196}/setup.py +7 -1
  4. {ultralytics-8.0.194 → ultralytics-8.0.196}/tests/conftest.py +6 -3
  5. {ultralytics-8.0.194 → ultralytics-8.0.196}/tests/test_cli.py +10 -1
  6. {ultralytics-8.0.194 → ultralytics-8.0.196}/tests/test_cuda.py +10 -0
  7. {ultralytics-8.0.194 → ultralytics-8.0.196}/tests/test_engine.py +5 -0
  8. {ultralytics-8.0.194 → ultralytics-8.0.196}/tests/test_python.py +117 -26
  9. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/__init__.py +1 -1
  10. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/__init__.py +5 -6
  11. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/augment.py +234 -29
  12. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/base.py +2 -1
  13. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/build.py +9 -3
  14. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/converter.py +5 -2
  15. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/dataset.py +16 -2
  16. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/loaders.py +111 -7
  17. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/utils.py +3 -3
  18. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/exporter.py +1 -3
  19. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/model.py +16 -9
  20. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/predictor.py +10 -6
  21. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/results.py +18 -8
  22. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/trainer.py +19 -31
  23. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/tuner.py +20 -20
  24. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/validator.py +3 -4
  25. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/hub/__init__.py +2 -2
  26. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/hub/auth.py +18 -3
  27. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/hub/session.py +1 -0
  28. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/hub/utils.py +1 -3
  29. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/model.py +2 -1
  30. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/predict.py +10 -7
  31. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/prompt.py +15 -1
  32. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/nas/model.py +3 -1
  33. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/rtdetr/model.py +4 -6
  34. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/rtdetr/predict.py +2 -1
  35. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/rtdetr/train.py +2 -1
  36. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/rtdetr/val.py +1 -0
  37. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/amg.py +12 -6
  38. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/model.py +5 -6
  39. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/decoders.py +5 -1
  40. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/encoders.py +15 -12
  41. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/tiny_encoder.py +38 -2
  42. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/transformer.py +2 -4
  43. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/predict.py +8 -4
  44. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/utils/loss.py +35 -8
  45. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/utils/ops.py +14 -18
  46. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/classify/predict.py +1 -0
  47. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/classify/train.py +4 -2
  48. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/classify/val.py +1 -0
  49. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/detect/train.py +4 -3
  50. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/model.py +2 -4
  51. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/pose/predict.py +1 -0
  52. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/segment/predict.py +2 -0
  53. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/segment/val.py +1 -1
  54. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/autobackend.py +54 -43
  55. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/__init__.py +13 -9
  56. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/block.py +11 -5
  57. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/conv.py +16 -7
  58. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/head.py +6 -3
  59. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/transformer.py +47 -15
  60. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/modules/utils.py +6 -4
  61. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/tasks.py +61 -21
  62. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/bot_sort.py +53 -6
  63. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/byte_tracker.py +71 -15
  64. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/track.py +0 -1
  65. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/utils/gmc.py +23 -0
  66. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/utils/kalman_filter.py +6 -6
  67. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/__init__.py +32 -19
  68. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/autobatch.py +1 -3
  69. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/benchmarks.py +14 -1
  70. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/base.py +1 -3
  71. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/comet.py +11 -3
  72. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/dvc.py +9 -0
  73. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/neptune.py +5 -6
  74. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/wb.py +1 -0
  75. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/checks.py +13 -9
  76. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/dist.py +2 -1
  77. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/downloads.py +7 -3
  78. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/files.py +3 -3
  79. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/instance.py +12 -3
  80. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/loss.py +97 -22
  81. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/metrics.py +35 -34
  82. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/ops.py +10 -9
  83. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/patches.py +9 -7
  84. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/plotting.py +4 -3
  85. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/torch_utils.py +8 -6
  86. ultralytics-8.0.196/ultralytics/utils/triton.py +87 -0
  87. {ultralytics-8.0.194 → ultralytics-8.0.196/ultralytics.egg-info}/PKG-INFO +1 -1
  88. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics.egg-info/SOURCES.txt +1 -0
  89. {ultralytics-8.0.194 → ultralytics-8.0.196}/CONTRIBUTING.md +0 -0
  90. {ultralytics-8.0.194 → ultralytics-8.0.196}/LICENSE +0 -0
  91. {ultralytics-8.0.194 → ultralytics-8.0.196}/MANIFEST.in +0 -0
  92. {ultralytics-8.0.194 → ultralytics-8.0.196}/README.md +0 -0
  93. {ultralytics-8.0.194 → ultralytics-8.0.196}/README.zh-CN.md +0 -0
  94. {ultralytics-8.0.194 → ultralytics-8.0.196}/requirements.txt +0 -0
  95. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/assets/bus.jpg +0 -0
  96. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/assets/zidane.jpg +0 -0
  97. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/Argoverse.yaml +0 -0
  98. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/DOTAv2.yaml +0 -0
  99. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/GlobalWheat2020.yaml +0 -0
  100. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/ImageNet.yaml +0 -0
  101. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/Objects365.yaml +0 -0
  102. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/SKU-110K.yaml +0 -0
  103. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/VOC.yaml +0 -0
  104. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/VisDrone.yaml +0 -0
  105. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco-pose.yaml +0 -0
  106. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco.yaml +0 -0
  107. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco128-seg.yaml +0 -0
  108. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco128.yaml +0 -0
  109. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco8-pose.yaml +0 -0
  110. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco8-seg.yaml +0 -0
  111. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/coco8.yaml +0 -0
  112. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/open-images-v7.yaml +0 -0
  113. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/tiger-pose.yaml +0 -0
  114. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/datasets/xView.yaml +0 -0
  115. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/default.yaml +0 -0
  116. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +0 -0
  117. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +0 -0
  118. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v3/yolov3-spp.yaml +0 -0
  119. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v3/yolov3-tiny.yaml +0 -0
  120. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v3/yolov3.yaml +0 -0
  121. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v5/yolov5-p6.yaml +0 -0
  122. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v5/yolov5.yaml +0 -0
  123. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v6/yolov6.yaml +0 -0
  124. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-cls.yaml +0 -0
  125. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-p2.yaml +0 -0
  126. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-p6.yaml +0 -0
  127. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +0 -0
  128. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-pose.yaml +0 -0
  129. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +0 -0
  130. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +0 -0
  131. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8-seg.yaml +0 -0
  132. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/models/v8/yolov8.yaml +0 -0
  133. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/trackers/botsort.yaml +0 -0
  134. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/cfg/trackers/bytetrack.yaml +0 -0
  135. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/__init__.py +0 -0
  136. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/data/annotator.py +0 -0
  137. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/engine/__init__.py +0 -0
  138. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/__init__.py +0 -0
  139. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/__init__.py +0 -0
  140. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/utils.py +0 -0
  141. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/fastsam/val.py +0 -0
  142. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/nas/__init__.py +0 -0
  143. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/nas/predict.py +0 -0
  144. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/nas/val.py +0 -0
  145. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/rtdetr/__init__.py +0 -0
  146. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/__init__.py +0 -0
  147. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/build.py +0 -0
  148. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/__init__.py +0 -0
  149. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/sam/modules/sam.py +0 -0
  150. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/utils/__init__.py +0 -0
  151. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/__init__.py +0 -0
  152. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/classify/__init__.py +0 -0
  153. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/detect/__init__.py +0 -0
  154. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/detect/predict.py +0 -0
  155. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/detect/val.py +0 -0
  156. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/pose/__init__.py +0 -0
  157. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/pose/train.py +0 -0
  158. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/pose/val.py +0 -0
  159. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/segment/__init__.py +0 -0
  160. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/models/yolo/segment/train.py +0 -0
  161. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/nn/__init__.py +0 -0
  162. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/__init__.py +0 -0
  163. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/basetrack.py +0 -0
  164. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/utils/__init__.py +0 -0
  165. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/trackers/utils/matching.py +0 -0
  166. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/__init__.py +0 -0
  167. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/clearml.py +0 -0
  168. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/hub.py +0 -0
  169. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/mlflow.py +0 -0
  170. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/raytune.py +0 -0
  171. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/callbacks/tensorboard.py +0 -0
  172. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/errors.py +0 -0
  173. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/tal.py +0 -0
  174. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics/utils/tuner.py +0 -0
  175. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics.egg-info/dependency_links.txt +0 -0
  176. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics.egg-info/entry_points.txt +0 -0
  177. {ultralytics-8.0.194 → ultralytics-8.0.196}/ultralytics.egg-info/requires.txt +0 -0
  178. {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.194
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
- """Add custom command-line options to pytest.
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
- """Register custom markers to avoid pytest warnings.
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
- """Setup hook to skip tests marked as slow if the --slow option is not provided.
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
- # Run a subprocess command with check=True
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
- # Test profile=True model argument
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
- # Write a list of sources (file, dir, glob, recursive glob) to a txt file
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
- # Convert SOURCE to greyscale and 4-ch
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
- # Test YouTube streaming inference (short 10 frame video) with non-default ByteTrack tracker
136
- # imgsz=160 required for tracking for higher confidence and better matches
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
- # TF suffers from install conflicts on Windows and macOS
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
- # TF suffers from install conflicts on Windows and macOS
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
- # Paddle protobuf requirements conflicting with onnx protobuf requirements
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
- # Test callback addition for prediction
242
- def on_predict_batch_end(predictor): # results -> List[batch_size]
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
- # Test functions in ultralytics/data/utils.py
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
- # Test dataset converters
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
- # Test event sending
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
- from ultralytics.utils.checks import (check_imgsz, check_imshow, check_requirements, check_version,
347
- check_yolov5u_filename, git_describe, print_args)
348
-
349
- check_yolov5u_filename('yolov5n.pt')
350
- # check_imshow(warn=True)
351
- git_describe(ROOT)
352
- check_requirements() # check requirements.txt
353
- check_imgsz([600, 600], max_dim=1)
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)
@@ -1,6 +1,6 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- __version__ = '8.0.194'
3
+ __version__ = '8.0.196'
4
4
 
5
5
  from ultralytics.models import RTDETR, SAM, YOLO
6
6
  from ultralytics.models.fastsam import FastSAM