a
    yf	b                     @   s*  d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	Z
ddlZddlZddlmZmZ ddlmZmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZ ddl m!Z!m"Z"m#Z# dd	l$m%Z% dd
l&m'Z' ddl(m)Z)m*Z* ed dddddddfddZ+G dd dZ,G dd dZ-dS )a  
Benchmark a YOLO model formats for speed and accuracy.

Usage:
    from ultralytics.utils.benchmarks import ProfileModels, benchmark
    ProfileModels(['yolov8n.yaml', 'yolov8s.yaml']).profile()
    benchmark(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.mlpackage
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/
NCNN                    | `ncnn`                    | yolov8n_ncnn_model/
    NPath)YOLO	YOLOWorld)	TASK2DATATASK2METRIC)export_formats)	ARM64ASSETS	IS_JETSONIS_RASPBERRYPILINUXLOGGERMACOSTQDMWEIGHTS_DIR)IS_PYTHON_3_12check_requirements
check_yolo)safe_download)	file_size)get_cpu_infoselect_devicez
yolov8n.pt   FcpuMbP?c                    s  ddl djj_djj_t|dd}t| ttfr>t	| } t
| jjd dd}g }	t }
ttt   D ]T\}\}}}}}d	\}}z|d
kr| jdksJ dnJ|dkrtrtrJ dn0|dv rtstsJ dtrJ dtrJ d|dv rtrJ d|dv r,t| tr,J d|dv rJt| trJJ d|dv rt| trhJ d|rvJ dtstsJ d|dv rt| trJ dd|jv r|sJ dd |jv r|sJ d!|d"kr| jp| j}| }n:| j|||||dd#}t	|| jd$}|t|v s4J d%d&}| jd'ksV|d
ksVJ d(|dvshJ d)|d*kst d+ksJ d,|dv r|rJ d-|jt d. |||d/ |pt!| j }t"| j }|j#|d0|d|||dd1}|j$| |j%d2  }}t&d3||  d4}|	'|d5t&t(|d0t&|d6t&|d4|g W qp t)y } zj|rzt|t*u szJ d7| d8| t+,d9| d8|  |	'||t&t(|d0dddg W Y d}~qpd}~0 0 qpt-|d: j.|	d;d<d=|d>d?gd@}t| jj/}dA| dB| dC| dDt |
 dEdF| dG}t+0| t1dHdIdJdKdL}|2| W d   n1 sb0    Y  |rt|t3r|| j4}| t5 fdMdN|D sJ dO  |S )Pa  
    Benchmark a YOLO model across different formats for speed and accuracy.

    Args:
        model (str | Path): Path to the model file or directory.
        data (str | None): Dataset to evaluate on, inherited from TASK2DATA if not passed.
        imgsz (int): Image size for the benchmark.
        half (bool): Use half-precision for the model if True.
        int8 (bool): Use int8-precision for the model if True.
        device (str): Device to run the benchmark on, either 'cpu' or 'cuda'.
        verbose (bool | float): If True or a float, assert benchmarks pass with given metric.
        eps (float): Epsilon value for divide by zero prevention.

    Returns:
        (pandas.DataFrame): A pandas DataFrame with benchmark results for each format, including file size, metric,
            and inference time.

    Examples:
        Benchmark a YOLO model with default settings:
        >>> from ultralytics.utils.benchmarks import benchmark
        >>> benchmark(model="yolov8n.pt", imgsz=640)
    r   N
   x   F)verboseZend2end)   ❌N   Zobbz.TensorFlow GraphDef not supported for OBB task	   z3Edge TPU export only supported on non-aarch64 Linux>   r      z9CoreML and TF.js export only supported on macOS and Linuxz5CoreML and TF.js export not supported on Raspberry Piz6CoreML and TF.js export not supported on NVIDIA Jetson>   r#   z#CoreML not supported on Python 3.12>         r!   z;YOLOWorldv2 TensorFlow exports not supported by onnx2tf yet>   r"   r   >      z,YOLOWorldv2 Paddle exports not supported yetz3End-to-end models not supported by PaddlePaddle yetz(Windows Paddle exports not supported yet>      z*YOLOWorldv2 NCNN exports not supported yetr   zinference not supported on CPUcudazinference not supported on GPU-)imgszformathalfint8devicer   )taskzexport failedu   ❎Zposez(GraphDef Pose inference is not supportedzinference not supportedr#   Darwinz(inference only supported on macOS>=10.13zHEnd-to-end torch.topk operation is not supported for NCNN prediction yetzbus.jpg)r*   r.   r,      )databatchr*   Zplotsr.   r,   r-   r   	inference     u   ✅   zBenchmark failure for : u#   ERROR ❌️ Benchmark failure for )r.   ZFormatu	   Status❔z	Size (MB)zInference time (ms/im)ZFPS)columnsz
Benchmarks complete for z on z
 at imgsz=z (z.2fzs)

zbenchmarks.logaignoreutf-8)errorsencodingc                 3   s    | ]} |r| kV  qd S N)Znotna).0xfloorpd X/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/utils/benchmarks.py	<genexpr>       zbenchmark.<locals>.<genexpr>z%Benchmark failure: metric(s) < floor )6ZpandasoptionsdisplayZmax_columnswidthr   
isinstancestrr   r   getattrmodeltime	enumeratezipr   valuesr/   r   r	   r   r   r   r   r   typeZ	ckpt_pathcfgexportplatformsystemZpredictr
   r   r   valZresults_dictspeedroundappendr   	ExceptionAssertionErrorr   warningr   Z	DataFramenameinfoopenwritefloatarrayall)rP   r2   r*   r,   r-   r.   r   epsZ
is_end2endyt0ira   r+   suffixr   gpuemojifilenameZexported_modelkeyresultsZmetricr[   ZfpsedfsfZmetricsrF   rC   rG   	benchmark1   s     

&





 

0"8
.
*
(rv   c                   @   s>   e Zd ZdZdd Zdd ZdddZed	d
 Zdd Z	dS )RF100BenchmarkzOBenchmark YOLO model performance across various formats for speed and accuracy.c                 C   s    g | _ g | _d| _g d| _dS )zcInitialize the RF100Benchmark class for benchmarking YOLO model performance across various formats.NclassZimagestargets	precisionZrecallmap50Zmap95)ds_namesds_cfg_listrfZval_metrics)selfrF   rF   rG   __init__   s    zRF100Benchmark.__init__c                 C   s$   t d ddlm} ||d| _dS )a%  
        Set Roboflow API key for processing.

        Args:
            api_key (str): The API key.

        Examples:
            Set the Roboflow API key for accessing datasets:
            >>> benchmark = RF100Benchmark()
            >>> benchmark.set_key("your_roboflow_api_key")
        roboflowr   )Roboflow)api_keyN)r   r   r   r   )r   r   r   rF   rF   rG   set_key   s    zRF100Benchmark.set_keydatasets_links.txtc           
   
   C   s"  t jdr tdt dfnt d t d t d td t|}|D ]}zt	
d| \}}}}}| j| | d| }	t|	 s| j|||d ntd | jt |	 d  W qT ty   Y qTY qT0 qTW d	   n1 s0    Y  | j| jfS )
a@  
        Parse dataset links and download datasets.

        Args:
            ds_link_txt (str): Path to the file containing dataset links.

        Examples:
            >>> benchmark = RF100Benchmark()
            >>> benchmark.set_key("api_key")
            >>> benchmark.parse_dataset("datasets_links.txt")
        zrf-100zultralytics-benchmarkszQhttps://github.com/ultralytics/assets/releases/download/v0.0.0/datasets_links.txtz/+r)   Zyolov8zDataset already downloaded.z	data.yamlN)ospathexistsshutilrmtreemkdirchdirr   rc   resplitstripr}   r]   r   r   	workspaceprojectversiondownloadprintr~   cwdr^   )
r   Zds_link_txtfileline_urlr   r   r   Zproj_versionrF   rF   rG   parse_dataset   s"    *


 ,zRF100Benchmark.parse_datasetc                 C   s|   t | }t|}W d   n1 s(0    Y  d|d< d|d< t | d}t|| W d   n1 sn0    Y  dS )z
        Fixes the train and validation paths in a given YAML file.

        Args:
            path (str): Path to the YAML file to be fixed.

        Examples:
            >>> RF100Benchmark.fix_yaml("path/to/data.yaml")
        Nztrain/imagestrainzvalid/imagesrZ   w)rc   yaml	safe_loadZ	safe_dump)r   r   Z	yaml_datarF   rF   rG   fix_yaml   s    
(zRF100Benchmark.fix_yamlc                    s|  g d}t |}t|d  W d   n1 s40    Y  t |dd}| }g }	|D ]`tfdd|D rxq\dttd	d
 dd D |	 fddD  q\W d   n1 s0    Y  d}
t	|	dkrt
d |	D ]}|d dkr|d }
qnt
d dd |	D d }
t |d,}|| j|  d|
 d W d   n1 sn0    Y  dS )a  
        Evaluate model performance on validation results.

        Args:
            yaml_path (str): Path to the YAML configuration file.
            val_log_file (str): Path to the validation log file.
            eval_log_file (str): Path to the evaluation log file.
            list_ind (int): Index of the current dataset in the list.

        Returns:
            (float): The mean average precision (mAP) value for the evaluated model.

        Examples:
            Evaluate a model on a specific dataset
            >>> benchmark = RF100Benchmark()
            >>> benchmark.evaluate("path/to/data.yaml", "path/to/val_log.txt", "path/to/eval_log.txt", 0)
        )u   🚀u   ⚠️u   💡r    namesNr=   )r?   c                 3   s   | ]}| v V  qd S r@   rF   )rA   symbol)r   rF   rG   rH     rI   z*RF100Benchmark.evaluate.<locals>.<genexpr> c                 S   s   | dkS )N rF   )rZ   rF   rF   rG   <lambda>  rI   z)RF100Benchmark.evaluate.<locals>.<lambda>c                 S   s   g | ]}| d qS )r:   )r   rA   rr   rF   rF   rG   
<listcomp>  rI   z+RF100Benchmark.evaluate.<locals>.<listcomp>c              	   3   s^   | ]V}| v s&|d krdvrdvrd d d d d d d	 d
V  qdS )rg   z(AP)z(AR)r   r1   r6      r7   r#   r%   rx   NrF   r   )class_namesentriesrF   rG   rH     s   
         r1   zThere's more dictsry   rg   r|   zThere's only one dict resc                 S   s   g | ]}|d  qS )r|   rF   )rA   resrF   rF   rG   r   -  rI   r   r;   r8   r:   )rc   r   r   	readlinesanyr   listfilterextendlenr   rd   r}   )r   Z	yaml_pathZval_log_fileZeval_log_fileZlist_indZskip_symbolsstreamru   linesZ
eval_linesZmap_vallstrF   )r   r   r   rG   evaluate   s2    
,

(zRF100Benchmark.evaluateN)r   )
__name__
__module____qualname____doc__r   r   r   staticmethodr   r   rF   rF   rF   rG   rw      s   
!
rw   c                   @   s   e Zd ZdZd#edd	d
Zdd Zdd ZedddZ	e
d$ddZd%eedddZd&eedddZdd Ze
dd  Ze
d!d" ZdS )'ProfileModelsa+  
    ProfileModels class for profiling different models on ONNX and TensorRT.

    This class profiles the performance of different models, returning results such as model speed and FLOPs.

    Attributes:
        paths (List[str]): Paths of the models to profile.
        num_timed_runs (int): Number of timed runs for the profiling.
        num_warmup_runs (int): Number of warmup runs before profiling.
        min_time (float): Minimum number of seconds to profile for.
        imgsz (int): Image size used in the models.
        half (bool): Flag to indicate whether to use FP16 half-precision for TensorRT profiling.
        trt (bool): Flag to indicate whether to profile using TensorRT.
        device (torch.device): Device used for profiling.

    Methods:
        profile: Profiles the models and prints the result.

    Examples:
        Profile models and print results
        >>> from ultralytics.utils.benchmarks import ProfileModels
        >>> profiler = ProfileModels(["yolov8n.yaml", "yolov8s.yaml"], imgsz=640)
        >>> profiler.profile()
    d   r   <     TN)pathsc	           	      C   sL   || _ || _|| _|| _|| _|| _|| _|pDttj	
 r@dnd| _dS )a[  
        Initialize the ProfileModels class for profiling models.

        Args:
            paths (List[str]): List of paths of the models to be profiled.
            num_timed_runs (int): Number of timed runs for the profiling.
            num_warmup_runs (int): Number of warmup runs before the actual profiling starts.
            min_time (float): Minimum time in seconds for profiling a model.
            imgsz (int): Size of the image used during profiling.
            half (bool): Flag to indicate whether to use FP16 half-precision for TensorRT profiling.
            trt (bool): Flag to indicate whether to profile using TensorRT.
            device (torch.device | None): Device used for profiling. If None, it is determined automatically.

        Notes:
            FP16 'half' argument option removed for ONNX as slower on CPU than FP32.

        Examples:
            Initialize and profile models
            >>> from ultralytics.utils.benchmarks import ProfileModels
            >>> profiler = ProfileModels(["yolov8n.yaml", "yolov8s.yaml"], imgsz=640)
            >>> profiler.profile()
        r   r   N)r   num_timed_runsnum_warmup_runsmin_timer*   r,   trttorchr.   r(   is_available)	r   r   r   r   r   r*   r,   r   r.   rF   rF   rG   r   M  s    !zProfileModels.__init__c              	   C   s  |   }|std dS g }g }|D ]}|d}|jdv rtt|}|  | }| jr| j	j
dkr| s|jd| j| j| j	dd}|jd	| j| j	dd
}n|jdkr$| |}|}nq$| t|}	| t|}
|| |j|
|	| || |j|
|	| q$| | |S )z_Profiles YOLO models for speed and accuracy across various formats including ONNX and TensorRT.z'No matching *.pt or *.onnx files found.Nz.engine   z.ptz.ymlz.yamlr   ZengineF)r+   r,   r*   r.   r   Zonnx)r+   r*   r.   r   z.onnx)	get_filesr   with_suffixrl   r   rN   Zfuserb   r   r.   rU   is_filerW   r,   r*   get_onnx_model_infoprofile_tensorrt_modelprofile_onnx_modelr]   generate_table_rowstemgenerate_results_dictprint_table)r   files
table_rowsoutputr   engine_filerP   
model_info	onnx_filet_enginet_onnxrF   rF   rG   profilew  sH    




zProfileModels.profilec                    s   g }| j D ]d t    r@g d}| fdd|D  q
 jdv rZ|t  q
|tt  q
tdt	|  dd t	|D S )zGReturns a list of paths for all relevant model files given by the user.)z*.ptz*.onnxz*.yamlc                    s(   g | ] }t  t | D ]}|qqS rF   )globrN   )rA   extr   r   rF   rG   r     rI   z+ProfileModels.get_files.<locals>.<listcomp>r   zProfiling: c                 S   s   g | ]}t |qS rF   r   )rA   r   rF   rF   rG   r     rI   )
r   r   is_dirr   rl   r]   rN   r   r   sorted)r   r   
extensionsrF   r   rG   r     s    

zProfileModels.get_files)r   c                 C   s   dS )zXExtracts metadata from an ONNX model file including parameters, GFLOPs, and input shape.)r   r   r   r   rF   )r   r   rF   rF   rG   r     s    z!ProfileModels.get_onnx_model_infor6   r   c                 C   sn   t | } t|D ]V}t | t |  }}| | |||  k| |||  k @  }t|t| krd qj|} q| S )ziApplies iterative sigma clipping to data to remove outliers based on specified sigma and iteration count.)nprf   rangemeanstdr   )r2   sigma	max_itersr   r   r   Zclipped_datarF   rF   rG   iterative_sigma_clipping  s    
$z&ProfileModels.iterative_sigma_clippingr   )r   rh   c                 C   s  | j rt| sdS t|}tj| j| jdtj	}d}t
dD ]8}t }t
| jD ]}||| jdd q\t | }qFtt| j||  | j | jd }g }	tt
||dD ](}||| jdd}
|	|
d jd	  q| jt|	d
dd}	t|	t|	fS )zaProfiles YOLO model performance with TensorRT, measuring average run time and standard deviation.)r   r   r   r   F)r*   r   2   descr   r4   r6   r   r   )r   r   r   r   r   randomrandr*   astypefloat32r   rQ   r   maxr\   r   r   r   r]   r[   r   rf   r   r   )r   r   rh   rP   
input_dataelapsedr   
start_timenum_runs	run_timesrq   rF   rF   rG   r     s"    $z$ProfileModels.profile_tensorrt_model)r   rh   c                 C   s  t d ddl}| }|jj|_d|_|j||dgd}| d }|j	}t
dd |jD  }|rvd	d
| j| jfn|j}	d|v rtj}
nNd|v rtj}
n>d|v rtj}
n.d|v rtj}
nd|v rtj}
ntd| tjj|	 |
}|j}| d j}d}td
D ]>}t }t| jD ]}||g||i q"t | }qtt| j||  | j | j }g }t!t||dD ]6}t }||g||i |"t | d  q| j#t$|ddd}t%|t&|fS )zeProfiles an ONNX model, measuring average inference time and standard deviation across multiple runs.onnxruntimer   Nr$   ZCPUExecutionProvider)	providersc                 s   s    | ]}t |to|d kV  qdS )r   N)rM   int)rA   dimrF   rF   rG   rH     rI   z3ProfileModels.profile_onnx_model.<locals>.<genexpr>r1   r   float16re   doubleint64int32zUnsupported ONNX datatype r   r   r5   r6   r#   r   )'r   r   ZSessionOptionsZGraphOptimizationLevelZORT_ENABLE_ALLZgraph_optimization_levelZintra_op_num_threadsZInferenceSession
get_inputsrU   rg   shaper*   r   r   r   Zfloat64r   r   
ValueErrorr   r   r   ra   get_outputsr   rQ   r   runr   r\   r   r   r   r]   r   rf   r   r   )r   r   rh   ZortZsess_optionssessZinput_tensorZ
input_typeZdynamicZinput_shapeZinput_dtyper   Z
input_nameZoutput_namer   r   r   r   r   rF   rF   rG   r     sL    
 z ProfileModels.profile_onnx_modelc           	      C   sf   |\}}}}d|dd| j  d|d dd|d dd	|d dd|d dd	|d
 dd|ddS )zhGenerates a table row string with model performance metrics including inference times and model details.z| Z18sz | z | - | r   z.1f   ±r1   z ms | g    .Az |)r*   )	r   
model_namer   r   r   layersparams	gradientsflopsrF   rF   rG   r     s    6z ProfileModels.generate_table_rowc                 C   s6   |\}}}}| |t |dt |d dt |d ddS )zhGenerates a dictionary of profiling results including model name, parameters, GFLOPs, and speed metrics.r   r   )z
model/namezmodel/parameterszmodel/GFLOPszmodel/speed_ONNX(ms)zmodel/speed_TensorRT(ms))r\   )r  r   r   r   r  r  r  r	  rF   rF   rG   r     s    z#ProfileModels.generate_results_dictc                 C   s   t j rt jdnd}ddddt  dd| d	d
dg}dddd |D  d }dddd |D  d }td|  t| | D ]}t| qdS )zZPrints a formatted table of model profiling results, including speed and accuracy metrics.r   ZGPUZModelzsize<br><sup>(pixels)zmAP<sup>val<br>50-95zSpeed<br><sup>CPU (z) ONNX<br>(ms)zSpeed<br><sup>z TensorRT<br>(ms)zparams<br><sup>(M)zFLOPs<br><sup>(B)|c                 s   s   | ]}d | d V  qdS )r   NrF   rA   hrF   rF   rG   rH   8  rI   z,ProfileModels.print_table.<locals>.<genexpr>c                 s   s   | ]}d t |d  V  qdS )r)   r6   N)r   r  rF   rF   rG   rH   9  rI   z

N)r   r(   r   Zget_device_namer   joinr   )r   rm   headersheader	separatorrowrF   rF   rG   r   +  s    
	zProfileModels.print_table)r   r   r   r   TTN)r6   r   )r   )r   )r   r   r   r   r   r   r   r   rN   r   r   r   re   r   r   r   r   r   rF   rF   rF   rG   r   3  s.          *,7
r   ).r   r   r   rX   r   r   rQ   pathlibr   numpyr   Z
torch.cudar   r   Zultralyticsr   r   Zultralytics.cfgr   r   Zultralytics.engine.exporterr   Zultralytics.utilsr	   r
   r   r   r   r   r   r   r   Zultralytics.utils.checksr   r   r   Zultralytics.utils.downloadsr   Zultralytics.utils.filesr   Zultralytics.utils.torch_utilsr   r   rv   rw   r   rF   rF   rF   rG   <module>   s<   ,
{ 