# Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license """ Benchmark a YOLO model formats for speed and accuracy Usage: from ultralytics.yolo.utils.benchmarks import run_benchmarks run_benchmarks(model='yolov8n.pt', imgsz=160) Format | `format=argument` | Model --- | --- | --- PyTorch | - | yolov8n.pt TorchScript | `torchscript` | yolov8n.torchscript ONNX | `onnx` | yolov8n.onnx OpenVINO | `openvino` | yolov8n_openvino_model/ TensorRT | `engine` | yolov8n.engine CoreML | `coreml` | yolov8n.mlmodel TensorFlow SavedModel | `saved_model` | yolov8n_saved_model/ TensorFlow GraphDef | `pb` | yolov8n.pb TensorFlow Lite | `tflite` | yolov8n.tflite TensorFlow Edge TPU | `edgetpu` | yolov8n_edgetpu.tflite TensorFlow.js | `tfjs` | yolov8n_web_model/ PaddlePaddle | `paddle` | yolov8n_paddle_model/ """ import platform import time from pathlib import Path from ultralytics import YOLO from ultralytics.yolo.engine.exporter import export_formats from ultralytics.yolo.utils import LINUX, LOGGER, MACOS, ROOT, SETTINGS from ultralytics.yolo.utils.checks import check_yolo from ultralytics.yolo.utils.downloads import download from ultralytics.yolo.utils.files import file_size from ultralytics.yolo.utils.torch_utils import select_device def benchmark(model=Path(SETTINGS['weights_dir']) / 'yolov8n.pt', imgsz=160, half=False, int8=False, device='cpu', hard_fail=False): """ Benchmark a YOLO model across different formats for speed and accuracy. Args: model (Union[str, Path], optional): Path to the model file or directory. Default is Path(SETTINGS['weights_dir']) / 'yolov8n.pt'. imgsz (int, optional): Image size for the benchmark. Default is 160. half (bool, optional): Use half-precision for the model if True. Default is False. int8 (bool, optional): Use int8-precision for the model if True. Default is False. device (str, optional): Device to run the benchmark on, either 'cpu' or 'cuda'. Default is 'cpu'. hard_fail (Union[bool, float], optional): If True or a float, assert benchmarks pass with given metric. Default is False. Returns: df (pandas.DataFrame): A pandas DataFrame with benchmark results for each format, including file size, metric, and inference time. """ import pandas as pd pd.options.display.max_columns = 10 pd.options.display.width = 120 device = select_device(device, verbose=False) if isinstance(model, (str, Path)): model = YOLO(model) y = [] t0 = time.time() for i, (name, format, suffix, cpu, gpu) in export_formats().iterrows(): # index, (name, format, suffix, CPU, GPU) emoji, filename = 'โŒ', None # export defaults try: assert i != 9 or LINUX, 'Edge TPU export only supported on Linux' if i == 10: assert MACOS or LINUX, 'TF.js export only supported on macOS and Linux' if 'cpu' in device.type: assert cpu, 'inference not supported on CPU' if 'cuda' in device.type: assert gpu, 'inference not supported on GPU' # Export if format == '-': filename = model.ckpt_path or model.cfg export = model # PyTorch format else: filename = model.export(imgsz=imgsz, format=format, half=half, int8=int8, device=device) # all others export = YOLO(filename, task=model.task) assert suffix in str(filename), 'export failed' emoji = 'โŽ' # indicates export succeeded # Predict assert i not in (9, 10), 'inference not supported' # Edge TPU and TF.js are unsupported assert i != 5 or platform.system() == 'Darwin', 'inference only supported on macOS>=10.13' # CoreML if not (ROOT / 'assets/bus.jpg').exists(): download(url='https://ultralytics.com/images/bus.jpg', dir=ROOT / 'assets') export.predict(ROOT / 'assets/bus.jpg', imgsz=imgsz, device=device, half=half) # Validate if model.task == 'detect': data, key = 'coco8.yaml', 'metrics/mAP50-95(B)' elif model.task == 'segment': data, key = 'coco8-seg.yaml', 'metrics/mAP50-95(M)' elif model.task == 'classify': data, key = 'imagenet100', 'metrics/accuracy_top5' elif model.task == 'pose': data, key = 'coco8-pose.yaml', 'metrics/mAP50-95(P)' results = export.val(data=data, batch=1, imgsz=imgsz, plots=False, device=device, half=half, int8=int8, verbose=False) metric, speed = results.results_dict[key], results.speed['inference'] y.append([name, 'โœ…', round(file_size(filename), 1), round(metric, 4), round(speed, 2)]) except Exception as e: if hard_fail: assert type(e) is AssertionError, f'Benchmark hard_fail for {name}: {e}' LOGGER.warning(f'ERROR โŒ๏ธ Benchmark failure for {name}: {e}') y.append([name, emoji, round(file_size(filename), 1), None, None]) # mAP, t_inference # Print results check_yolo(device=device) # print system info df = pd.DataFrame(y, columns=['Format', 'Statusโ”', 'Size (MB)', key, 'Inference time (ms/im)']) name = Path(model.ckpt_path).name s = f'\nBenchmarks complete for {name} on {data} at imgsz={imgsz} ({time.time() - t0:.2f}s)\n{df}\n' LOGGER.info(s) with open('benchmarks.log', 'a', errors='ignore', encoding='utf-8') as f: f.write(s) if hard_fail and isinstance(hard_fail, float): metrics = df[key].array # values to compare to floor floor = hard_fail # minimum metric floor to pass, i.e. = 0.29 mAP for YOLOv5n assert all(x > floor for x in metrics if pd.notna(x)), f'HARD FAIL: one or more metric(s) < floor {floor}' return df if __name__ == '__main__': benchmark()