ultralytics 8.2.9__tar.gz → 8.2.11__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 (219) hide show
  1. {ultralytics-8.2.9/ultralytics.egg-info → ultralytics-8.2.11}/PKG-INFO +2 -2
  2. {ultralytics-8.2.9 → ultralytics-8.2.11}/pyproject.toml +1 -1
  3. {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_cli.py +2 -2
  4. {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_cuda.py +32 -0
  5. {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_exports.py +76 -17
  6. {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_python.py +21 -36
  7. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/__init__.py +1 -1
  8. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/__init__.py +1 -0
  9. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/base.py +1 -1
  10. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/exporter.py +80 -19
  11. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/results.py +22 -16
  12. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/model.py +3 -3
  13. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/checks.py +1 -1
  14. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/downloads.py +1 -1
  15. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/tuner.py +1 -1
  16. {ultralytics-8.2.9 → ultralytics-8.2.11/ultralytics.egg-info}/PKG-INFO +2 -2
  17. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics.egg-info/requires.txt +1 -1
  18. {ultralytics-8.2.9 → ultralytics-8.2.11}/LICENSE +0 -0
  19. {ultralytics-8.2.9 → ultralytics-8.2.11}/README.md +0 -0
  20. {ultralytics-8.2.9 → ultralytics-8.2.11}/setup.cfg +0 -0
  21. {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_engine.py +0 -0
  22. {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_explorer.py +0 -0
  23. {ultralytics-8.2.9 → ultralytics-8.2.11}/tests/test_integrations.py +0 -0
  24. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/assets/bus.jpg +0 -0
  25. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/assets/zidane.jpg +0 -0
  26. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/Argoverse.yaml +0 -0
  27. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/DOTAv1.5.yaml +0 -0
  28. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/DOTAv1.yaml +0 -0
  29. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/GlobalWheat2020.yaml +0 -0
  30. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/ImageNet.yaml +0 -0
  31. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/Objects365.yaml +0 -0
  32. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/SKU-110K.yaml +0 -0
  33. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/VOC.yaml +0 -0
  34. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/VisDrone.yaml +0 -0
  35. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/african-wildlife.yaml +0 -0
  36. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/brain-tumor.yaml +0 -0
  37. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/carparts-seg.yaml +0 -0
  38. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco-pose.yaml +0 -0
  39. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco.yaml +0 -0
  40. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco128-seg.yaml +0 -0
  41. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco128.yaml +0 -0
  42. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco8-pose.yaml +0 -0
  43. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco8-seg.yaml +0 -0
  44. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/coco8.yaml +0 -0
  45. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/crack-seg.yaml +0 -0
  46. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/dota8.yaml +0 -0
  47. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/lvis.yaml +0 -0
  48. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/open-images-v7.yaml +0 -0
  49. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/package-seg.yaml +0 -0
  50. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/tiger-pose.yaml +0 -0
  51. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/datasets/xView.yaml +0 -0
  52. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/default.yaml +0 -0
  53. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +0 -0
  54. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +0 -0
  55. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +0 -0
  56. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +0 -0
  57. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v3/yolov3-spp.yaml +0 -0
  58. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v3/yolov3-tiny.yaml +0 -0
  59. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v3/yolov3.yaml +0 -0
  60. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v5/yolov5-p6.yaml +0 -0
  61. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v5/yolov5.yaml +0 -0
  62. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v6/yolov6.yaml +0 -0
  63. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +0 -0
  64. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +0 -0
  65. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-cls.yaml +0 -0
  66. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +0 -0
  67. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +0 -0
  68. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-ghost.yaml +0 -0
  69. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-obb.yaml +0 -0
  70. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-p2.yaml +0 -0
  71. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-p6.yaml +0 -0
  72. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +0 -0
  73. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-pose.yaml +0 -0
  74. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +0 -0
  75. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +0 -0
  76. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-seg.yaml +0 -0
  77. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-world.yaml +0 -0
  78. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8-worldv2.yaml +0 -0
  79. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v8/yolov8.yaml +0 -0
  80. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v9/yolov9c-seg.yaml +0 -0
  81. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v9/yolov9c.yaml +0 -0
  82. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v9/yolov9e-seg.yaml +0 -0
  83. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/models/v9/yolov9e.yaml +0 -0
  84. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/trackers/botsort.yaml +0 -0
  85. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/cfg/trackers/bytetrack.yaml +0 -0
  86. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/__init__.py +0 -0
  87. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/annotator.py +0 -0
  88. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/augment.py +0 -0
  89. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/build.py +0 -0
  90. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/converter.py +0 -0
  91. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/dataset.py +0 -0
  92. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/explorer/__init__.py +0 -0
  93. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/explorer/explorer.py +0 -0
  94. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/explorer/gui/__init__.py +0 -0
  95. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/explorer/gui/dash.py +0 -0
  96. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/explorer/utils.py +0 -0
  97. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/loaders.py +0 -0
  98. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/split_dota.py +0 -0
  99. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/data/utils.py +0 -0
  100. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/__init__.py +0 -0
  101. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/model.py +0 -0
  102. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/predictor.py +0 -0
  103. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/trainer.py +0 -0
  104. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/tuner.py +0 -0
  105. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/engine/validator.py +0 -0
  106. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/hub/__init__.py +0 -0
  107. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/hub/auth.py +0 -0
  108. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/hub/session.py +0 -0
  109. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/hub/utils.py +0 -0
  110. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/__init__.py +0 -0
  111. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/__init__.py +0 -0
  112. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/model.py +0 -0
  113. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/predict.py +0 -0
  114. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/prompt.py +0 -0
  115. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/utils.py +0 -0
  116. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/fastsam/val.py +0 -0
  117. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/nas/__init__.py +0 -0
  118. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/nas/model.py +0 -0
  119. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/nas/predict.py +0 -0
  120. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/nas/val.py +0 -0
  121. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/rtdetr/__init__.py +0 -0
  122. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/rtdetr/model.py +0 -0
  123. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/rtdetr/predict.py +0 -0
  124. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/rtdetr/train.py +0 -0
  125. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/rtdetr/val.py +0 -0
  126. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/__init__.py +0 -0
  127. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/amg.py +0 -0
  128. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/build.py +0 -0
  129. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/model.py +0 -0
  130. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/__init__.py +0 -0
  131. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/decoders.py +0 -0
  132. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/encoders.py +0 -0
  133. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/sam.py +0 -0
  134. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/tiny_encoder.py +0 -0
  135. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/modules/transformer.py +0 -0
  136. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/sam/predict.py +0 -0
  137. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/utils/__init__.py +0 -0
  138. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/utils/loss.py +0 -0
  139. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/utils/ops.py +0 -0
  140. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/__init__.py +0 -0
  141. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/classify/__init__.py +0 -0
  142. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/classify/predict.py +0 -0
  143. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/classify/train.py +0 -0
  144. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/classify/val.py +0 -0
  145. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/detect/__init__.py +0 -0
  146. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/detect/predict.py +0 -0
  147. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/detect/train.py +0 -0
  148. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/detect/val.py +0 -0
  149. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/obb/__init__.py +0 -0
  150. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/obb/predict.py +0 -0
  151. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/obb/train.py +0 -0
  152. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/obb/val.py +0 -0
  153. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/pose/__init__.py +0 -0
  154. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/pose/predict.py +0 -0
  155. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/pose/train.py +0 -0
  156. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/pose/val.py +0 -0
  157. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/segment/__init__.py +0 -0
  158. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/segment/predict.py +0 -0
  159. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/segment/train.py +0 -0
  160. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/segment/val.py +0 -0
  161. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/world/__init__.py +0 -0
  162. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/world/train.py +0 -0
  163. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/models/yolo/world/train_world.py +0 -0
  164. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/__init__.py +0 -0
  165. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/autobackend.py +0 -0
  166. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/__init__.py +0 -0
  167. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/block.py +0 -0
  168. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/conv.py +0 -0
  169. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/head.py +0 -0
  170. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/transformer.py +0 -0
  171. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/modules/utils.py +0 -0
  172. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/nn/tasks.py +0 -0
  173. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/__init__.py +0 -0
  174. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/ai_gym.py +0 -0
  175. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/distance_calculation.py +0 -0
  176. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/heatmap.py +0 -0
  177. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/object_counter.py +0 -0
  178. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/parking_management.py +0 -0
  179. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/queue_management.py +0 -0
  180. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/solutions/speed_estimation.py +0 -0
  181. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/__init__.py +0 -0
  182. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/basetrack.py +0 -0
  183. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/bot_sort.py +0 -0
  184. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/byte_tracker.py +0 -0
  185. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/track.py +0 -0
  186. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/utils/__init__.py +0 -0
  187. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/utils/gmc.py +0 -0
  188. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/utils/kalman_filter.py +0 -0
  189. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/trackers/utils/matching.py +0 -0
  190. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/__init__.py +0 -0
  191. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/autobatch.py +0 -0
  192. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/benchmarks.py +0 -0
  193. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/__init__.py +0 -0
  194. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/base.py +0 -0
  195. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/clearml.py +0 -0
  196. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/comet.py +0 -0
  197. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/dvc.py +0 -0
  198. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/hub.py +0 -0
  199. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/mlflow.py +0 -0
  200. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/neptune.py +0 -0
  201. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/raytune.py +0 -0
  202. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/tensorboard.py +0 -0
  203. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/callbacks/wb.py +0 -0
  204. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/dist.py +0 -0
  205. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/errors.py +0 -0
  206. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/files.py +0 -0
  207. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/instance.py +0 -0
  208. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/loss.py +0 -0
  209. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/metrics.py +0 -0
  210. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/ops.py +0 -0
  211. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/patches.py +0 -0
  212. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/plotting.py +0 -0
  213. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/tal.py +0 -0
  214. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/torch_utils.py +0 -0
  215. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics/utils/triton.py +0 -0
  216. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics.egg-info/SOURCES.txt +0 -0
  217. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics.egg-info/dependency_links.txt +0 -0
  218. {ultralytics-8.2.9 → ultralytics-8.2.11}/ultralytics.egg-info/entry_points.txt +0 -0
  219. {ultralytics-8.2.9 → ultralytics-8.2.11}/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.2.9
3
+ Version: 8.2.11
4
4
  Summary: Ultralytics YOLOv8 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
5
5
  Author: Glenn Jocher, Ayush Chaurasia, Jing Qiu
6
6
  Maintainer: Glenn Jocher, Ayush Chaurasia, Jing Qiu
@@ -77,7 +77,7 @@ Requires-Dist: dvclive>=2.12.0; extra == "logging"
77
77
  Provides-Extra: extra
78
78
  Requires-Dist: hub-sdk>=0.0.5; extra == "extra"
79
79
  Requires-Dist: ipython; extra == "extra"
80
- Requires-Dist: albumentations<=1.4.4,>=1.0.3; extra == "extra"
80
+ Requires-Dist: albumentations>=1.4.6; extra == "extra"
81
81
  Requires-Dist: pycocotools>=2.0.7; extra == "extra"
82
82
 
83
83
  <div align="center">
@@ -123,7 +123,7 @@ logging = [
123
123
  extra = [
124
124
  "hub-sdk>=0.0.5", # Ultralytics HUB
125
125
  "ipython", # interactive notebook
126
- "albumentations>=1.0.3,<=1.4.4", # training augmentations
126
+ "albumentations>=1.4.6", # training augmentations
127
127
  "pycocotools>=2.0.7", # COCO mAP
128
128
  ]
129
129
 
@@ -54,8 +54,8 @@ def test_export(model):
54
54
 
55
55
  def test_rtdetr(task="detect", model="yolov8n-rtdetr.yaml", data="coco8.yaml"):
56
56
  """Test the RTDETR functionality with the Ultralytics framework."""
57
- # Warning: MUST use imgsz=640
58
- run(f"yolo train {task} model={model} data={data} --imgsz= 160 epochs =1, cache = disk") # add coma, spaces to args
57
+ # Warning: must use imgsz=640 (note also add coma, spaces, fraction=0.25 args to test single-image training)
58
+ run(f"yolo train {task} model={model} data={data} --imgsz= 160 epochs =1, cache = disk fraction=0.25")
59
59
  run(f"yolo predict {task} model={model} source={ASSETS / 'bus.jpg'} imgsz=160 save save_crop save_txt")
60
60
 
61
61
 
@@ -1,10 +1,14 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
+ from pathlib import Path
4
+ from itertools import product
5
+
3
6
  import pytest
4
7
  import torch
5
8
 
6
9
  from ultralytics import YOLO
7
10
  from ultralytics.utils import ASSETS, WEIGHTS_DIR
11
+ from ultralytics.cfg import TASK2DATA, TASK2MODEL, TASKS
8
12
 
9
13
  from . import CUDA_DEVICE_COUNT, CUDA_IS_AVAILABLE, MODEL, SOURCE
10
14
 
@@ -23,6 +27,34 @@ def test_export_engine():
23
27
  YOLO(f)(SOURCE, device=0)
24
28
 
25
29
 
30
+ @pytest.mark.slow
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 exports to TensorRT format."""
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
+ )
53
+ YOLO(file)([SOURCE] * batch, imgsz=64 if dynamic else 32) # exported model inference
54
+ Path(file).unlink() # cleanup
55
+ Path(file).with_suffix(".cache").unlink() if int8 else None # cleanup INT8 cache
56
+
57
+
26
58
  @pytest.mark.skipif(not CUDA_IS_AVAILABLE, reason="CUDA is not available")
27
59
  def test_train():
28
60
  """Test model training on a minimal dataset."""
@@ -18,24 +18,18 @@ from ultralytics.utils import (
18
18
  checks,
19
19
  )
20
20
  from ultralytics.utils.torch_utils import TORCH_1_9, TORCH_1_13
21
- from . import MODEL, SOURCE
22
21
 
23
- # Constants
24
- EXPORT_PARAMETERS_LIST = [ # generate all combinations but exclude those where both int8 and half are True
25
- (task, dynamic, int8, half, batch)
26
- for task, dynamic, int8, half, batch in product(TASKS, [True, False], [True, False], [True, False], [1, 2])
27
- if not (int8 and half) # exclude cases where both int8 and half are True
28
- ]
22
+ from . import MODEL, SOURCE
29
23
 
30
24
 
31
25
  def test_export_torchscript():
32
- """Test exporting the YOLO model to TorchScript format."""
26
+ """Test YOLO exports to TorchScript format."""
33
27
  f = YOLO(MODEL).export(format="torchscript", optimize=False, imgsz=32)
34
28
  YOLO(f)(SOURCE, imgsz=32) # exported model inference
35
29
 
36
30
 
37
31
  def test_export_onnx():
38
- """Test exporting the YOLO model to ONNX format."""
32
+ """Test YOLO exports to ONNX format."""
39
33
  f = YOLO(MODEL).export(format="onnx", dynamic=True, imgsz=32)
40
34
  YOLO(f)(SOURCE, imgsz=32) # exported model inference
41
35
 
@@ -43,7 +37,7 @@ def test_export_onnx():
43
37
  @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="OpenVINO not supported in Python 3.12")
44
38
  @pytest.mark.skipif(not TORCH_1_13, reason="OpenVINO requires torch>=1.13")
45
39
  def test_export_openvino():
46
- """Test exporting the YOLO model to OpenVINO format."""
40
+ """Test YOLO exports to OpenVINO format."""
47
41
  f = YOLO(MODEL).export(format="openvino", imgsz=32)
48
42
  YOLO(f)(SOURCE, imgsz=32) # exported model inference
49
43
 
@@ -51,9 +45,16 @@ def test_export_openvino():
51
45
  @pytest.mark.slow
52
46
  @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="OpenVINO not supported in Python 3.12")
53
47
  @pytest.mark.skipif(not TORCH_1_13, reason="OpenVINO requires torch>=1.13")
54
- @pytest.mark.parametrize("task, dynamic, int8, half, batch", EXPORT_PARAMETERS_LIST)
48
+ @pytest.mark.parametrize(
49
+ "task, dynamic, int8, half, batch",
50
+ [ # generate all combinations but exclude those where both int8 and half are True
51
+ (task, dynamic, int8, half, batch)
52
+ for task, dynamic, int8, half, batch in product(TASKS, [True, False], [True, False], [True, False], [1, 2])
53
+ if not (int8 and half) # exclude cases where both int8 and half are True
54
+ ],
55
+ )
55
56
  def test_export_openvino_matrix(task, dynamic, int8, half, batch):
56
- """Test exporting the YOLO model to OpenVINO format."""
57
+ """Test YOLO exports to OpenVINO format."""
57
58
  file = YOLO(TASK2MODEL[task]).export(
58
59
  format="openvino",
59
60
  imgsz=32,
@@ -73,12 +74,70 @@ def test_export_openvino_matrix(task, dynamic, int8, half, batch):
73
74
  shutil.rmtree(file)
74
75
 
75
76
 
77
+ @pytest.mark.slow
78
+ @pytest.mark.parametrize("task, dynamic, int8, half, batch", product(TASKS, [True, False], [False], [False], [1, 2]))
79
+ def test_export_onnx_matrix(task, dynamic, int8, half, batch):
80
+ """Test YOLO exports to ONNX format."""
81
+ file = YOLO(TASK2MODEL[task]).export(
82
+ format="onnx",
83
+ imgsz=32,
84
+ dynamic=dynamic,
85
+ int8=int8,
86
+ half=half,
87
+ batch=batch,
88
+ )
89
+ YOLO(file)([SOURCE] * batch, imgsz=64 if dynamic else 32) # exported model inference
90
+ Path(file).unlink() # cleanup
91
+
92
+
93
+ @pytest.mark.slow
94
+ @pytest.mark.parametrize("task, dynamic, int8, half, batch", product(TASKS, [False], [False], [False], [1, 2]))
95
+ def test_export_torchscript_matrix(task, dynamic, int8, half, batch):
96
+ """Test YOLO exports to TorchScript format."""
97
+ file = YOLO(TASK2MODEL[task]).export(
98
+ format="torchscript",
99
+ imgsz=32,
100
+ dynamic=dynamic,
101
+ int8=int8,
102
+ half=half,
103
+ batch=batch,
104
+ )
105
+ YOLO(file)([SOURCE] * 3, imgsz=64 if dynamic else 32) # exported model inference at batch=3
106
+ Path(file).unlink() # cleanup
107
+
108
+
109
+ @pytest.mark.slow
110
+ @pytest.mark.skipif(not MACOS, reason="CoreML inference only supported on macOS")
111
+ @pytest.mark.skipif(not TORCH_1_9, reason="CoreML>=7.2 not supported with PyTorch<=1.8")
112
+ @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="CoreML not supported in Python 3.12")
113
+ @pytest.mark.parametrize(
114
+ "task, dynamic, int8, half, batch",
115
+ [ # generate all combinations but exclude those where both int8 and half are True
116
+ (task, dynamic, int8, half, batch)
117
+ for task, dynamic, int8, half, batch in product(TASKS, [False], [True, False], [True, False], [1])
118
+ if not (int8 and half) # exclude cases where both int8 and half are True
119
+ ],
120
+ )
121
+ def test_export_coreml_matrix(task, dynamic, int8, half, batch):
122
+ """Test YOLO exports to TorchScript format."""
123
+ file = YOLO(TASK2MODEL[task]).export(
124
+ format="coreml",
125
+ imgsz=32,
126
+ dynamic=dynamic,
127
+ int8=int8,
128
+ half=half,
129
+ batch=batch,
130
+ )
131
+ YOLO(file)([SOURCE] * batch, imgsz=32) # exported model inference at batch=3
132
+ shutil.rmtree(file) # cleanup
133
+
134
+
76
135
  @pytest.mark.skipif(not TORCH_1_9, reason="CoreML>=7.2 not supported with PyTorch<=1.8")
77
136
  @pytest.mark.skipif(WINDOWS, reason="CoreML not supported on Windows") # RuntimeError: BlobWriter not loaded
78
137
  @pytest.mark.skipif(IS_RASPBERRYPI, reason="CoreML not supported on Raspberry Pi")
79
138
  @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="CoreML not supported in Python 3.12")
80
139
  def test_export_coreml():
81
- """Test exporting the YOLO model to CoreML format."""
140
+ """Test YOLO exports to CoreML format."""
82
141
  if MACOS:
83
142
  f = YOLO(MODEL).export(format="coreml", imgsz=32)
84
143
  YOLO(f)(SOURCE, imgsz=32) # model prediction only supported on macOS for nms=False models
@@ -89,7 +148,7 @@ def test_export_coreml():
89
148
  @pytest.mark.skipif(not LINUX, reason="Test disabled as TF suffers from install conflicts on Windows and macOS")
90
149
  def test_export_tflite():
91
150
  """
92
- Test exporting the YOLO model to TFLite format.
151
+ Test YOLO exports to TFLite format.
93
152
 
94
153
  Note TF suffers from install conflicts on Windows and macOS.
95
154
  """
@@ -102,7 +161,7 @@ def test_export_tflite():
102
161
  @pytest.mark.skipif(not LINUX, reason="TF suffers from install conflicts on Windows and macOS")
103
162
  def test_export_pb():
104
163
  """
105
- Test exporting the YOLO model to *.pb format.
164
+ Test YOLO exports to *.pb format.
106
165
 
107
166
  Note TF suffers from install conflicts on Windows and macOS.
108
167
  """
@@ -114,7 +173,7 @@ def test_export_pb():
114
173
  @pytest.mark.skipif(True, reason="Test disabled as Paddle protobuf and ONNX protobuf requirementsk conflict.")
115
174
  def test_export_paddle():
116
175
  """
117
- Test exporting the YOLO model to Paddle format.
176
+ Test YOLO exports to Paddle format.
118
177
 
119
178
  Note Paddle protobuf requirements conflicting with onnx protobuf requirements.
120
179
  """
@@ -123,6 +182,6 @@ def test_export_paddle():
123
182
 
124
183
  @pytest.mark.slow
125
184
  def test_export_ncnn():
126
- """Test exporting the YOLO model to NCNN format."""
185
+ """Test YOLO exports to NCNN format."""
127
186
  f = YOLO(MODEL).export(format="ncnn", imgsz=32)
128
187
  YOLO(f)(SOURCE, imgsz=32) # exported model inference
@@ -12,7 +12,7 @@ import yaml
12
12
  from PIL import Image
13
13
 
14
14
  from ultralytics import RTDETR, YOLO
15
- from ultralytics.cfg import TASK2DATA
15
+ from ultralytics.cfg import MODELS, TASK2DATA
16
16
  from ultralytics.data.build import load_inference_source
17
17
  from ultralytics.utils import (
18
18
  ASSETS,
@@ -76,42 +76,27 @@ def test_predict_txt():
76
76
  _ = YOLO(MODEL)(source=txt_file, imgsz=32)
77
77
 
78
78
 
79
- def test_predict_img():
79
+ @pytest.mark.parametrize("model_name", MODELS)
80
+ def test_predict_img(model_name):
80
81
  """Test YOLO prediction on various types of image sources."""
81
- model = YOLO(MODEL)
82
- seg_model = YOLO(WEIGHTS_DIR / "yolov8n-seg.pt")
83
- cls_model = YOLO(WEIGHTS_DIR / "yolov8n-cls.pt")
84
- pose_model = YOLO(WEIGHTS_DIR / "yolov8n-pose.pt")
85
- obb_model = YOLO(WEIGHTS_DIR / "yolov8n-obb.pt")
86
- im = cv2.imread(str(SOURCE))
82
+ model = YOLO(WEIGHTS_DIR / model_name)
83
+ im = cv2.imread(str(SOURCE)) # uint8 numpy array
87
84
  assert len(model(source=Image.open(SOURCE), save=True, verbose=True, imgsz=32)) == 1 # PIL
88
85
  assert len(model(source=im, save=True, save_txt=True, imgsz=32)) == 1 # ndarray
86
+ assert len(model(torch.rand((2, 3, 32, 32)), imgsz=32)) == 2 # batch-size 2 Tensor, FP32 0.0-1.0 RGB order
89
87
  assert len(model(source=[im, im], save=True, save_txt=True, imgsz=32)) == 2 # batch
90
88
  assert len(list(model(source=[im, im], save=True, stream=True, imgsz=32))) == 2 # stream
91
- assert len(model(torch.zeros(320, 640, 3).numpy(), imgsz=32)) == 1 # tensor to numpy
89
+ assert len(model(torch.zeros(320, 640, 3).numpy().astype(np.uint8), imgsz=32)) == 1 # tensor to numpy
92
90
  batch = [
93
91
  str(SOURCE), # filename
94
92
  Path(SOURCE), # Path
95
93
  "https://ultralytics.com/images/zidane.jpg" if ONLINE else SOURCE, # URI
96
94
  cv2.imread(str(SOURCE)), # OpenCV
97
95
  Image.open(SOURCE), # PIL
98
- np.zeros((320, 640, 3)),
99
- ] # numpy
96
+ np.zeros((320, 640, 3), dtype=np.uint8), # numpy
97
+ ]
100
98
  assert len(model(batch, imgsz=32)) == len(batch) # multiple sources in a batch
101
99
 
102
- # Test tensor inference
103
- im = torch.rand((4, 3, 32, 32)) # batch-size 4, FP32 0.0-1.0 RGB order
104
- results = model(im, imgsz=32)
105
- assert len(results) == im.shape[0]
106
- results = seg_model(im, imgsz=32)
107
- assert len(results) == im.shape[0]
108
- results = cls_model(im, imgsz=32)
109
- assert len(results) == im.shape[0]
110
- results = pose_model(im, imgsz=32)
111
- assert len(results) == im.shape[0]
112
- results = obb_model(im, imgsz=32)
113
- assert len(results) == im.shape[0]
114
-
115
100
 
116
101
  def test_predict_grey_and_4ch():
117
102
  """Test YOLO prediction on SOURCE converted to greyscale and 4-channel images."""
@@ -236,19 +221,19 @@ def test_predict_callback_and_setup():
236
221
  print(boxes)
237
222
 
238
223
 
239
- def test_results():
224
+ @pytest.mark.parametrize("model", MODELS)
225
+ def test_results(model):
240
226
  """Test various result formats for the YOLO model."""
241
- for m in "yolov8n-pose.pt", "yolov8n-seg.pt", "yolov8n.pt", "yolov8n-cls.pt":
242
- results = YOLO(WEIGHTS_DIR / m)([SOURCE, SOURCE], imgsz=160)
243
- for r in results:
244
- r = r.cpu().numpy()
245
- r = r.to(device="cpu", dtype=torch.float32)
246
- r.save_txt(txt_file=TMP / "runs/tests/label.txt", save_conf=True)
247
- r.save_crop(save_dir=TMP / "runs/tests/crops/")
248
- r.tojson(normalize=True)
249
- r.plot(pil=True)
250
- r.plot(conf=True, boxes=True)
251
- print(r, len(r), r.path)
227
+ results = YOLO(WEIGHTS_DIR / model)([SOURCE, SOURCE], imgsz=160)
228
+ for r in results:
229
+ r = r.cpu().numpy()
230
+ r = r.to(device="cpu", dtype=torch.float32)
231
+ r.save_txt(txt_file=TMP / "runs/tests/label.txt", save_conf=True)
232
+ r.save_crop(save_dir=TMP / "runs/tests/crops/")
233
+ r.tojson(normalize=True)
234
+ r.plot(pil=True)
235
+ r.plot(conf=True, boxes=True)
236
+ print(r, len(r), r.path)
252
237
 
253
238
 
254
239
  def test_labels_and_crops():
@@ -1,6 +1,6 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- __version__ = "8.2.9"
3
+ __version__ = "8.2.11"
4
4
 
5
5
  from ultralytics.data.explorer.explorer import Explorer
6
6
  from ultralytics.models import RTDETR, SAM, YOLO, YOLOWorld
@@ -53,6 +53,7 @@ TASK2METRIC = {
53
53
  "pose": "metrics/mAP50-95(P)",
54
54
  "obb": "metrics/mAP50-95(B)",
55
55
  }
56
+ MODELS = {TASK2MODEL[task] for task in TASKS}
56
57
 
57
58
  ARGV = sys.argv or ["", ""] # sometimes sys.argv = []
58
59
  CLI_HELP_MSG = f"""
@@ -170,7 +170,7 @@ class BaseDataset(Dataset):
170
170
  if self.augment:
171
171
  self.ims[i], self.im_hw0[i], self.im_hw[i] = im, (h0, w0), im.shape[:2] # im, hw_original, hw_resized
172
172
  self.buffer.append(i)
173
- if len(self.buffer) >= self.max_buffer_length:
173
+ if 1 < len(self.buffer) >= self.max_buffer_length: # prevent empty buffer
174
174
  j = self.buffer.pop(0)
175
175
  if self.cache != "ram":
176
176
  self.ims[j], self.im_hw0[j], self.im_hw[j] = None, None, None
@@ -88,7 +88,7 @@ from ultralytics.utils import (
88
88
  yaml_save,
89
89
  )
90
90
  from ultralytics.utils.checks import check_imgsz, check_is_path_safe, check_requirements, check_version
91
- from ultralytics.utils.downloads import attempt_download_asset, get_github_assets
91
+ from ultralytics.utils.downloads import attempt_download_asset, get_github_assets, safe_download
92
92
  from ultralytics.utils.files import file_size, spaces_in_path
93
93
  from ultralytics.utils.ops import Profile
94
94
  from ultralytics.utils.torch_utils import TORCH_1_13, get_latest_opset, select_device, smart_inference_mode
@@ -200,6 +200,8 @@ class Exporter:
200
200
  self.args.half = False
201
201
  assert not self.args.dynamic, "half=True not compatible with dynamic=True, i.e. use only one."
202
202
  self.imgsz = check_imgsz(self.args.imgsz, stride=model.stride, min_dim=2) # check image size
203
+ if self.args.int8 and engine:
204
+ self.args.dynamic = True # enforce dynamic to export TensorRT INT8; ensures ONNX is dynamic
203
205
  if self.args.optimize:
204
206
  assert not ncnn, "optimize=True not compatible with format='ncnn', i.e. use optimize=False"
205
207
  assert self.device.type == "cpu", "optimize=True not compatible with cuda devices, i.e. use device='cpu'"
@@ -349,12 +351,12 @@ class Exporter:
349
351
  task=self.model.task,
350
352
  imgsz=self.imgsz[0],
351
353
  augment=False,
352
- batch_size=self.args.batch,
354
+ batch_size=self.args.batch * 2, # NOTE TensorRT INT8 calibration should use 2x batch size
353
355
  )
354
356
  n = len(dataset)
355
357
  if n < 300:
356
358
  LOGGER.warning(f"{prefix} WARNING ⚠️ >300 images recommended for INT8 calibration, found {n} images.")
357
- return build_dataloader(dataset, batch=self.args.batch, workers=0) # required for batch loading
359
+ return build_dataloader(dataset, batch=self.args.batch * 2, workers=0) # required for batch loading
358
360
 
359
361
  @try_export
360
362
  def export_torchscript(self, prefix=colorstr("TorchScript:")):
@@ -533,7 +535,7 @@ class Exporter:
533
535
  f_ts = self.file.with_suffix(".torchscript")
534
536
 
535
537
  name = Path("pnnx.exe" if WINDOWS else "pnnx") # PNNX filename
536
- pnnx = name if name.is_file() else ROOT / name
538
+ pnnx = name if name.is_file() else (ROOT / name)
537
539
  if not pnnx.is_file():
538
540
  LOGGER.warning(
539
541
  f"{prefix} WARNING ⚠️ PNNX not found. Attempting to download binary file from "
@@ -542,19 +544,19 @@ class Exporter:
542
544
  )
543
545
  system = "macos" if MACOS else "windows" if WINDOWS else "linux-aarch64" if ARM64 else "linux"
544
546
  try:
545
- _, assets = get_github_assets(repo="pnnx/pnnx")
546
- url = [x for x in assets if f"{system}.zip" in x][0]
547
- assert url, "Unable to retrieve PNNX repo assets"
547
+ release, assets = get_github_assets(repo="pnnx/pnnx")
548
+ asset = [x for x in assets if f"{system}.zip" in x][0]
549
+ assert isinstance(asset, str), "Unable to retrieve PNNX repo assets" # i.e. pnnx-20240410-macos.zip
550
+ LOGGER.info(f"{prefix} successfully found latest PNNX asset file {asset}")
548
551
  except Exception as e:
549
- url = f"https://github.com/pnnx/pnnx/releases/download/20240410/pnnx-20240410-{system}.zip"
550
- LOGGER.warning(f"{prefix} WARNING ⚠️ PNNX GitHub assets not found: {e}, using default {url}")
551
- asset = attempt_download_asset(url, repo="pnnx/pnnx", release="latest")
552
- if check_is_path_safe(Path.cwd(), asset): # avoid path traversal security vulnerability
553
- unzip_dir = Path(asset).with_suffix("")
552
+ release = "20240410"
553
+ asset = f"pnnx-{release}-{system}.zip"
554
+ LOGGER.warning(f"{prefix} WARNING ⚠️ PNNX GitHub assets not found: {e}, using default {asset}")
555
+ unzip_dir = safe_download(f"https://github.com/pnnx/pnnx/releases/download/{release}/{asset}", delete=True)
556
+ if check_is_path_safe(Path.cwd(), unzip_dir): # avoid path traversal security vulnerability
554
557
  (unzip_dir / name).rename(pnnx) # move binary to ROOT
555
- shutil.rmtree(unzip_dir) # delete unzip dir
556
- Path(asset).unlink() # delete zip
557
558
  pnnx.chmod(0o777) # set read, write, and execute permissions for everyone
559
+ shutil.rmtree(unzip_dir) # delete unzip dir
558
560
 
559
561
  ncnn_args = [
560
562
  f'ncnnparam={f / "model.ncnn.param"}',
@@ -599,6 +601,7 @@ class Exporter:
599
601
 
600
602
  LOGGER.info(f"\n{prefix} starting export with coremltools {ct.__version__}...")
601
603
  assert not WINDOWS, "CoreML export is not supported on Windows, please run on macOS or Linux."
604
+ assert self.args.batch == 1, "CoreML batch sizes > 1 are not supported. Please retry at 'batch=1'."
602
605
  f = self.file.with_suffix(".mlmodel" if mlmodel else ".mlpackage")
603
606
  if f.is_dir():
604
607
  shutil.rmtree(f)
@@ -678,6 +681,7 @@ class Exporter:
678
681
  import tensorrt as trt # noqa
679
682
  check_version(trt.__version__, "7.0.0", hard=True) # require tensorrt>=7.0.0
680
683
 
684
+ # Setup and checks
681
685
  LOGGER.info(f"\n{prefix} starting export with TensorRT {trt.__version__}...")
682
686
  is_trt10 = int(trt.__version__.split(".")[0]) >= 10 # is TensorRT >= 10
683
687
  assert Path(f_onnx).exists(), f"failed to export ONNX file: {f_onnx}"
@@ -686,6 +690,7 @@ class Exporter:
686
690
  if self.args.verbose:
687
691
  logger.min_severity = trt.Logger.Severity.VERBOSE
688
692
 
693
+ # Engine builder
689
694
  builder = trt.Builder(logger)
690
695
  config = builder.create_builder_config()
691
696
  workspace = int(self.args.workspace * (1 << 30))
@@ -695,10 +700,14 @@ class Exporter:
695
700
  config.max_workspace_size = workspace
696
701
  flag = 1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)
697
702
  network = builder.create_network(flag)
703
+ half = builder.platform_has_fast_fp16 and self.args.half
704
+ int8 = builder.platform_has_fast_int8 and self.args.int8
705
+ # Read ONNX file
698
706
  parser = trt.OnnxParser(network, logger)
699
707
  if not parser.parse_from_file(f_onnx):
700
708
  raise RuntimeError(f"failed to load ONNX file: {f_onnx}")
701
709
 
710
+ # Network inputs
702
711
  inputs = [network.get_input(i) for i in range(network.num_inputs)]
703
712
  outputs = [network.get_output(i) for i in range(network.num_outputs)]
704
713
  for inp in inputs:
@@ -712,15 +721,67 @@ class Exporter:
712
721
  LOGGER.warning(f"{prefix} WARNING ⚠️ 'dynamic=True' model requires max batch size, i.e. 'batch=16'")
713
722
  profile = builder.create_optimization_profile()
714
723
  min_shape = (1, shape[1], 32, 32) # minimum input shape
715
- opt_shape = (max(1, shape[0] // 2), *shape[1:]) # optimal input shape
716
724
  max_shape = (*shape[:2], *(max(1, self.args.workspace) * d for d in shape[2:])) # max input shape
717
725
  for inp in inputs:
718
- profile.set_shape(inp.name, min_shape, opt_shape, max_shape)
726
+ profile.set_shape(inp.name, min=min_shape, opt=shape, max=max_shape)
719
727
  config.add_optimization_profile(profile)
720
728
 
721
- half = builder.platform_has_fast_fp16 and self.args.half
722
- LOGGER.info(f"{prefix} building FP{16 if half else 32} engine as {f}")
723
- if half:
729
+ LOGGER.info(f"{prefix} building {'INT8' if int8 else 'FP' + ('16' if half else '32')} engine as {f}")
730
+ if int8:
731
+ config.set_flag(trt.BuilderFlag.INT8)
732
+ config.set_calibration_profile(profile)
733
+ config.profiling_verbosity = trt.ProfilingVerbosity.DETAILED
734
+
735
+ class EngineCalibrator(trt.IInt8Calibrator):
736
+ def __init__(
737
+ self,
738
+ dataset, # ultralytics.data.build.InfiniteDataLoader
739
+ batch: int,
740
+ cache: str = "",
741
+ ) -> None:
742
+ trt.IInt8Calibrator.__init__(self)
743
+ self.dataset = dataset
744
+ self.data_iter = iter(dataset)
745
+ self.algo = trt.CalibrationAlgoType.ENTROPY_CALIBRATION_2
746
+ self.batch = batch
747
+ self.cache = Path(cache)
748
+
749
+ def get_algorithm(self) -> trt.CalibrationAlgoType:
750
+ """Get the calibration algorithm to use."""
751
+ return self.algo
752
+
753
+ def get_batch_size(self) -> int:
754
+ """Get the batch size to use for calibration."""
755
+ return self.batch or 1
756
+
757
+ def get_batch(self, names) -> list:
758
+ """Get the next batch to use for calibration, as a list of device memory pointers."""
759
+ try:
760
+ im0s = next(self.data_iter)["img"] / 255.0
761
+ im0s = im0s.to("cuda") if im0s.device.type == "cpu" else im0s
762
+ return [int(im0s.data_ptr())]
763
+ except StopIteration:
764
+ # Return [] or None, signal to TensorRT there is no calibration data remaining
765
+ return None
766
+
767
+ def read_calibration_cache(self) -> bytes:
768
+ """Use existing cache instead of calibrating again, otherwise, implicitly return None."""
769
+ if self.cache.exists() and self.cache.suffix == ".cache":
770
+ return self.cache.read_bytes()
771
+
772
+ def write_calibration_cache(self, cache) -> None:
773
+ """Write calibration cache to disk."""
774
+ _ = self.cache.write_bytes(cache)
775
+
776
+ # Load dataset w/ builder (for batching) and calibrate
777
+ dataset = self.get_int8_calibration_dataloader(prefix)
778
+ config.int8_calibrator = EngineCalibrator(
779
+ dataset=dataset,
780
+ batch=2 * self.args.batch,
781
+ cache=self.file.with_suffix(".cache"),
782
+ )
783
+
784
+ elif half:
724
785
  config.set_flag(trt.BuilderFlag.FP16)
725
786
 
726
787
  # Free CUDA memory
@@ -387,26 +387,32 @@ class Results(SimpleClass):
387
387
 
388
388
  def summary(self, normalize=False, decimals=5):
389
389
  """Convert the results to a summarized format."""
390
- if self.probs is not None:
391
- LOGGER.warning("Warning: Classify results do not support the `summary()` method yet.")
392
- return
393
-
394
390
  # Create list of detection dictionaries
395
391
  results = []
396
- data = self.boxes.data.cpu().tolist()
392
+ if self.probs is not None:
393
+ class_id = self.probs.top1
394
+ results.append(
395
+ {
396
+ "name": self.names[class_id],
397
+ "class": class_id,
398
+ "confidence": round(self.probs.top1conf.item(), decimals),
399
+ }
400
+ )
401
+ return results
402
+
403
+ data = self.boxes or self.obb
404
+ is_obb = self.obb is not None
397
405
  h, w = self.orig_shape if normalize else (1, 1)
398
406
  for i, row in enumerate(data): # xyxy, track_id if tracking, conf, class_id
399
- box = {
400
- "x1": round(row[0] / w, decimals),
401
- "y1": round(row[1] / h, decimals),
402
- "x2": round(row[2] / w, decimals),
403
- "y2": round(row[3] / h, decimals),
404
- }
405
- conf = round(row[-2], decimals)
406
- class_id = int(row[-1])
407
- result = {"name": self.names[class_id], "class": class_id, "confidence": conf, "box": box}
408
- if self.boxes.is_track:
409
- result["track_id"] = int(row[-3]) # track ID
407
+ class_id, conf = int(row.cls), round(row.conf.item(), decimals)
408
+ box = (row.xyxyxyxy if is_obb else row.xyxy).squeeze().reshape(-1, 2).tolist()
409
+ xy = {}
410
+ for i, b in enumerate(box):
411
+ xy[f"x{i + 1}"] = round(b[0] / w, decimals)
412
+ xy[f"y{i + 1}"] = round(b[1] / h, decimals)
413
+ result = {"name": self.names[class_id], "class": class_id, "confidence": conf, "box": xy}
414
+ if data.is_track:
415
+ result["track_id"] = int(row.id.item()) # track ID
410
416
  if self.masks:
411
417
  result["segments"] = {
412
418
  "x": (self.masks.xy[i][:, 0] / w).round(decimals).tolist(),
@@ -15,7 +15,7 @@ class YOLO(Model):
15
15
  """Initialize YOLO model, switching to YOLOWorld if model filename contains '-world'."""
16
16
  path = Path(model)
17
17
  if "-world" in path.stem and path.suffix in {".pt", ".yaml", ".yml"}: # if YOLOWorld PyTorch model
18
- new_instance = YOLOWorld(path)
18
+ new_instance = YOLOWorld(path, verbose=verbose)
19
19
  self.__class__ = type(new_instance)
20
20
  self.__dict__ = new_instance.__dict__
21
21
  else:
@@ -62,14 +62,14 @@ class YOLO(Model):
62
62
  class YOLOWorld(Model):
63
63
  """YOLO-World object detection model."""
64
64
 
65
- def __init__(self, model="yolov8s-world.pt") -> None:
65
+ def __init__(self, model="yolov8s-world.pt", verbose=False) -> None:
66
66
  """
67
67
  Initializes the YOLOv8-World model with the given pre-trained model file. Supports *.pt and *.yaml formats.
68
68
 
69
69
  Args:
70
70
  model (str | Path): Path to the pre-trained model. Defaults to 'yolov8s-world.pt'.
71
71
  """
72
- super().__init__(model=model, task="detect")
72
+ super().__init__(model=model, task="detect", verbose=verbose)
73
73
 
74
74
  # Assign default COCO class names when there are no custom names
75
75
  if not hasattr(self.model, "names"):
@@ -528,7 +528,7 @@ def check_is_path_safe(basedir, path):
528
528
  base_dir_resolved = Path(basedir).resolve()
529
529
  path_resolved = Path(path).resolve()
530
530
 
531
- return path_resolved.is_file() and path_resolved.parts[: len(base_dir_resolved.parts)] == base_dir_resolved.parts
531
+ return path_resolved.exists() and path_resolved.parts[: len(base_dir_resolved.parts)] == base_dir_resolved.parts
532
532
 
533
533
 
534
534
  def check_imshow(warn=False):
@@ -418,7 +418,7 @@ def attempt_download_asset(file, repo="ultralytics/assets", release="v8.2.0", **
418
418
 
419
419
  Example:
420
420
  ```python
421
- file_path = attempt_download_asset('yolov5s.pt', repo='ultralytics/assets', release='latest')
421
+ file_path = attempt_download_asset('yolov8n.pt', repo='ultralytics/assets', release='latest')
422
422
  ```
423
423
  """
424
424
  from ultralytics.utils import SETTINGS # scoped for circular import