Skip to content

Commit

Permalink
Update check_requirements() single install (#9353)
Browse files Browse the repository at this point in the history
* Update `check_requirements()` single install

Faster install and better conflict resolution with single installation

Signed-off-by: Glenn Jocher <glenn.jocher@ultralytics.com>

* Update

* Update

* Update

Signed-off-by: Glenn Jocher <glenn.jocher@ultralytics.com>
  • Loading branch information
glenn-jocher committed Sep 10, 2022
1 parent 8aa196c commit 24bf9cc
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 35 deletions.
12 changes: 6 additions & 6 deletions export.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def export_torchscript(model, im, file, optimize, prefix=colorstr('TorchScript:'
@try_export
def export_onnx(model, im, file, opset, train, dynamic, simplify, prefix=colorstr('ONNX:')):
# YOLOv5 ONNX export
check_requirements(('onnx',))
check_requirements('onnx')
import onnx

LOGGER.info(f'\n{prefix} starting export with onnx {onnx.__version__}...')
Expand Down Expand Up @@ -182,7 +182,7 @@ def export_onnx(model, im, file, opset, train, dynamic, simplify, prefix=colorst
@try_export
def export_openvino(model, file, half, prefix=colorstr('OpenVINO:')):
# YOLOv5 OpenVINO export
check_requirements(('openvino-dev',)) # requires openvino-dev: https://pypi.org/project/openvino-dev/
check_requirements('openvino-dev') # requires openvino-dev: https://pypi.org/project/openvino-dev/
import openvino.inference_engine as ie

LOGGER.info(f'\n{prefix} starting export with openvino {ie.__version__}...')
Expand All @@ -198,7 +198,7 @@ def export_openvino(model, file, half, prefix=colorstr('OpenVINO:')):
@try_export
def export_coreml(model, im, file, int8, half, prefix=colorstr('CoreML:')):
# YOLOv5 CoreML export
check_requirements(('coremltools',))
check_requirements('coremltools')
import coremltools as ct

LOGGER.info(f'\n{prefix} starting export with coremltools {ct.__version__}...')
Expand Down Expand Up @@ -226,7 +226,7 @@ def export_engine(model, im, file, half, dynamic, simplify, workspace=4, verbose
import tensorrt as trt
except Exception:
if platform.system() == 'Linux':
check_requirements(('nvidia-tensorrt',), cmds=('-U --index-url https://pypi.ngc.nvidia.com',))
check_requirements('nvidia-tensorrt', cmds=['-U --index-url https://pypi.ngc.nvidia.com'])
import tensorrt as trt

if trt.__version__[0] == '7': # TensorRT 7 handling https://github.com/ultralytics/yolov5/issues/6012
Expand Down Expand Up @@ -405,7 +405,7 @@ def export_edgetpu(file, prefix=colorstr('Edge TPU:')):
@try_export
def export_tfjs(file, prefix=colorstr('TensorFlow.js:')):
# YOLOv5 TensorFlow.js export
check_requirements(('tensorflowjs',))
check_requirements('tensorflowjs')
import re

import tensorflowjs as tfjs
Expand Down Expand Up @@ -516,7 +516,7 @@ def run(
# TensorFlow Exports
if any((saved_model, pb, tflite, edgetpu, tfjs)):
if int8 or edgetpu: # TFLite --int8 bug https://github.com/ultralytics/yolov5/issues/5707
check_requirements(('flatbuffers==1.12',)) # required before `import tensorflow`
check_requirements('flatbuffers==1.12') # required before `import tensorflow`
assert not tflite or not tfjs, 'TFLite and TF.js models must be exported separately, please pass only one type.'
assert not isinstance(model, ClassificationModel), 'ClassificationModel export to TF formats not yet supported.'
f[5], model = export_saved_model(model.cpu(),
Expand Down
4 changes: 2 additions & 2 deletions models/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ def __init__(self, weights='yolov5s.pt', device=torch.device('cpu'), dnn=False,
stride, names = int(d['stride']), d['names']
elif dnn: # ONNX OpenCV DNN
LOGGER.info(f'Loading {w} for ONNX OpenCV DNN inference...')
check_requirements(('opencv-python>=4.5.4',))
check_requirements('opencv-python>=4.5.4')
net = cv2.dnn.readNetFromONNX(w)
elif onnx: # ONNX Runtime
LOGGER.info(f'Loading {w} for ONNX Runtime inference...')
Expand All @@ -362,7 +362,7 @@ def __init__(self, weights='yolov5s.pt', device=torch.device('cpu'), dnn=False,
stride, names = int(meta['stride']), eval(meta['names'])
elif xml: # OpenVINO
LOGGER.info(f'Loading {w} for OpenVINO inference...')
check_requirements(('openvino',)) # requires openvino-dev: https://pypi.org/project/openvino-dev/
check_requirements('openvino') # requires openvino-dev: https://pypi.org/project/openvino-dev/
from openvino.runtime import Core, Layout, get_batch
ie = Core()
if not Path(w).is_file(): # if not *.xml
Expand Down
48 changes: 23 additions & 25 deletions utils/general.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,39 +342,37 @@ def check_version(current='0.0.0', minimum='0.0.0', name='version ', pinned=Fals

@TryExcept()
def check_requirements(requirements=ROOT / 'requirements.txt', exclude=(), install=True, cmds=()):
# Check installed dependencies meet YOLOv5 requirements (pass *.txt file or list of packages)
# Check installed dependencies meet YOLOv5 requirements (pass *.txt file or list of packages or single package str)
prefix = colorstr('red', 'bold', 'requirements:')
check_python() # check python version
if isinstance(requirements, (str, Path)): # requirements.txt file
file = Path(requirements)
if isinstance(requirements, Path): # requirements.txt file
file = requirements
assert file.exists(), f"{prefix} {file.resolve()} not found, check failed."
with file.open() as f:
requirements = [f'{x.name}{x.specifier}' for x in pkg.parse_requirements(f) if x.name not in exclude]
else: # list or tuple of packages
requirements = [x for x in requirements if x not in exclude]
elif isinstance(requirements, str):
requirements = [requirements]

n = 0 # number of packages updates
for i, r in enumerate(requirements):
s = ''
n = 0
for r in requirements:
try:
pkg.require(r)
except Exception: # DistributionNotFound or VersionConflict if requirements not met
s = f"{prefix} {r} not found and is required by YOLOv5"
if install and AUTOINSTALL: # check environment variable
LOGGER.info(f"{s}, attempting auto-update...")
try:
assert check_online(), f"'pip install {r}' skipped (offline)"
LOGGER.info(check_output(f'pip install "{r}" {cmds[i] if cmds else ""}', shell=True).decode())
n += 1
except Exception as e:
LOGGER.warning(f'{prefix} {e}')
else:
LOGGER.info(f'{s}. Please install and rerun your command.')

if n: # if packages updated
source = file.resolve() if 'file' in locals() else requirements
s = f"{prefix} {n} package{'s' * (n > 1)} updated per {source}\n" \
f"{prefix} ⚠️ {colorstr('bold', 'Restart runtime or rerun command for updates to take effect')}\n"
LOGGER.info(s)
except (pkg.VersionConflict, pkg.DistributionNotFound): # exception if requirements not met
s += f'"{r}" '
n += 1

if s and install and AUTOINSTALL: # check environment variable
LOGGER.info(f"{prefix} YOLOv5 requirements {s}not found, attempting AutoUpdate...")
try:
assert check_online(), "AutoUpdate skipped (offline)"
LOGGER.info(check_output(f'pip install {s} {" ".join(cmds) if cmds else ""}', shell=True).decode())
source = file.resolve() if 'file' in locals() else requirements
s = f"{prefix} {n} package{'s' * (n > 1)} updated per {source}\n" \
f"{prefix} ⚠️ {colorstr('bold', 'Restart runtime or rerun command for updates to take effect')}\n"
LOGGER.info(s)
except Exception as e:
LOGGER.warning(f'{prefix} {e}')


def check_img_size(imgsz, s=32, floor=0):
Expand Down
4 changes: 2 additions & 2 deletions val.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def run(
json.dump(jdict, f)

try: # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb
check_requirements(['pycocotools'])
check_requirements('pycocotools')
from pycocotools.coco import COCO
from pycocotools.cocoeval import COCOeval

Expand Down Expand Up @@ -360,7 +360,7 @@ def parse_opt():


def main(opt):
check_requirements(requirements=ROOT / 'requirements.txt', exclude=('tensorboard', 'thop'))
check_requirements(exclude=('tensorboard', 'thop'))

if opt.task in ('train', 'val', 'test'): # run normally
if opt.conf_thres > 0.001: # https://github.com/ultralytics/yolov5/issues/1466
Expand Down

0 comments on commit 24bf9cc

Please sign in to comment.