
    sgN                        d dl Z d dl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 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  ed
      Zg dZ G d de      ZdededefdZdefdZd Zdededee
e   e
e   e	ef   fdZ 	 d1dedededee   def
dZ!dede"dede#fdZ$dede"defd Z%	 	 	 d2dededede"dee   de#defd!Z&d"edefd#Z'd"edefd$Z(d%efd&Z)e*d'k(  rY e       Z+e+jY                         Z- ee-j\                        j_                         e-_.        	  e0d(        e&e-jb                  e-jd                  e-j\                  e-jf                  e-jh                  e-jj                  e-j$                         e-jP                  rU ee       e-jb                  d)k(  r e0d*        e0d+        e'e-j\                        e-_6         e(e-jl                        e-_7        e-jp                  rR e0d,        e)e-j\                          e9e-d-      r e)e-jl                          e9e-d.      r e)e-jn                         yyyy# e:$ rZ; e0d/e;         e<d0       Y dZ;[;ydZ;[;ww xY w)3    N)ArgumentParser)listdirmakedirs)Path)DictListOptionalTuple)Versionparse)Pipelinepipeline)BatchEncoding)ModelOutputis_tf_availableis_torch_availablez1.4.0)	feature-extractionnerzsentiment-analysisz	fill-maskzquestion-answeringztext-generationtranslation_en_to_frtranslation_en_to_detranslation_en_to_roc                   "     e Zd ZdZ fdZ xZS )OnnxConverterArgumentParserz[
    Wraps all the script arguments supported to export transformers models to ONNX IR
    c                    t         |   d       | j                  dt        t        d       | j                  dt        dd       | j                  d	t        d
       | j                  dt        ddgd       | j                  dt
        dd       | j                  ddd       | j                  ddd       | j                  ddd       | j                  d       y )NzONNX Converterz
--pipeliner   )typechoicesdefaultz--modelTz4Model's id or path (ex: google-bert/bert-base-cased))r   requiredhelpz--tokenizerz8Tokenizer's id or path (ex: google-bert/bert-base-cased))r   r   z--frameworkpttfzFramework for loading the model)r   r   r   z--opset   zONNX opset to use)r   r   r   z--check-loading
store_truez$Check ONNX is able to load the model)actionr   z--use-external-formatz!Allow exporting model >= than 2Gbz
--quantizez/Quantize the neural network to be run with int8output)super__init__add_argumentstrSUPPORTED_PIPELINESint)self	__class__s    U/var/www/html/venv/lib/python3.12/site-packages/transformers/convert_graph_to_onnx.pyr'   z$OnnxConverterArgumentParser.__init__3   s   )*'(	 	 	
 	G	 	 	
 	-c8rs4L2	 	 	
 	)#r@ST7 	 	

 	#4 	 	

 	B 	 	

 	(#    )__name__
__module____qualname____doc__r'   __classcell__)r-   s   @r.   r   r   .   s    &$ &$r/   r   filename
identifierreturnc                     | j                   j                  | j                  |z         j                  | j                        S )aE  
    Append a string-identifier at the end (before the extension, if any) to the provided filepath

    Args:
        filename: pathlib.Path The actual path object we would like to add an identifier suffix
        identifier: The suffix to add

    Returns: String with concatenated identifier at the end of the filename
    )parentjoinpathstemwith_suffixsuffix)r5   r6   s     r.   generate_identified_filenamer>   \   s1     ??##HMMJ$>?KKHOO\\r/   minimum_versionc                     	 ddl }t        |j                        }|t        k  rt	        d|j                   d|  d      y# t        $ r t	        d      w xY w)z
    Check onnxruntime is installed and if the installed version match is recent enough

    Raises:
        ImportError: If onnxruntime is not installed or too old version is found
    r   Nz*We found an older version of onnxruntime (z&) but we require onnxruntime to be >= zp to enable all the conversions options.
Please update onnxruntime by running `pip install --upgrade onnxruntime`zonnxruntime doesn't seem to be currently installed. Please install the onnxruntime by running `pip install onnxruntime` and relaunch the conversion.)onnxruntimer   __version__ORT_QUANTIZE_MINIMUM_VERSIONImportError)r?   rA   ort_versions      r.   check_onnxruntime_requirementsrF   i   s    
 K334 55<[=T=T<U V77F6G H[[  6  
,
 	

s   >A Ac                    t        d       | j                  j                  j                  }g g }}|dd D ];  }||v r&|j	                  |       |j	                  ||          -t        | d        n t        d|        |t        |      fS )a  
    Ensure inputs are presented in the correct order, without any Non

    Args:
        model: The model used to forward the input data
        tokens: BatchEncoding holding the input data
        input_names: The name of the inputs

    Returns: Tuple

    z$Ensuring inputs are in correct order   Nz, is not present in the generated input list.zGenerated inputs order: )printforward__code__co_varnamesappendtuple)modeltokensinput_namesmodel_args_name
model_argsordered_input_namesarg_names          r.   ensure_valid_inputrV      s     

01mm,,88O&("#J#AB' {"&&x0fX./XJJKL 
$%8$9
:;j 111r/   nlp	frameworkc                 :   dt         dt        dt        ffd| j                  d|      }|j                  j
                  d   }|dk(  r | j                  di |n| j                  |      }t        |t              r|j                         }t        |t        t        f      s|f}t        |j                               }|j                         D ci c]  \  }}| ||d	|       }}}g }	|D ];  }
t        |
t        t        f      r|	j                  |
       +|	j                  |
       = t!        t#        |	            D cg c]  }d
| 	 }}t%        ||	      D ci c]  \  }}| ||d|       }}}t'        |fi |}||||fS c c}}w c c}w c c}}w )a?  
    Attempt to infer the static vs dynamic axes for each input and output tensors for a specific model

    Args:
        nlp: The pipeline object holding the model to be exported
        framework: The framework identifier to dispatch to the correct inference scheme (pt/tf)

    Returns:

        - List of the inferred input variable names
        - List of the inferred output variable names
        - Dictionary with input/output variables names as key and shape tensor as value
        - a BatchEncoding reference which was used to infer all the above information
    nameis_inputseq_lenc           	      F   t        |t        t        f      r|D cg c]  } | |||       c}S t        |j                        D cg c]  \  }}|dk(  s| c}}d   di}|r@t        |j                        dk(  rd|d<   not        dt        |j                         d      t        |j                        D 	cg c]  \  }}	|	|k(  s| }
}}	|j                  |
D ci c]  }|d c}       t        d|rd	nd
 d|  d|        |S c c}w c c}}w c c}	}w c c}w )NrH   r   batch   sequencezUnable to infer tensor axes ()zFound inputr%    z with shape: )	
isinstancerN   list	enumerateshapelen
ValueErrorupdaterI   )rZ   tensorr[   r\   taxisnumelaxesdimrg   seq_axesbuild_shape_dicts              r.   rr   z&infer_shapes.<locals>.build_shape_dict   s   fudm,JPQQ$T1h@QQ .7v||-DSkdEQR
TSTUVX_`Dv||$)(DG$'DSEVDWWX%YZZ2;FLL2I^JCUV]M]C^^AS*_AB(w94&dVTU R T _As#   D	DD>DD"
DzThis is a sample output)return_tensorsr    Toutput_F )r)   boolr+   	tokenizer	input_idsrg   rO   rd   r   to_tuplere   rN   keysitemsextendrM   rangerh   zipdict)rW   rX   rP   r\   outputs
input_varskvinput_dynamic_axesoutputs_flatr%   ioutput_namesoutput_dynamic_axesdynamic_axesrr   s                  @r.   infer_shapesr      s    s d S & ]]4Y]OF$$R(G%.$%6icii!&!CIIf<MG';'""$ge}-* fkkm$JOU||~^tq!!-aD'BB^^ L (fudm,''	( ,1\1B+CDagaSMDLDQTUacoQpqA1.q!UGDDqq *B.ABL|\699! _ Eqs   FF!Fpipeline_namerO   rx   c                     ||}|dk(  rt               st        d      |dk(  rt               st        d      t        d| d| d       t	        | ||||      S )	a  
    Convert the set of arguments provided through the CLI to an actual pipeline reference (tokenizer + model

    Args:
        pipeline_name: The kind of pipeline to use (ner, question-answering, etc.)
        framework: The actual model to convert the pipeline from ("pt" or "tf")
        model: The model name which will be loaded by the pipeline
        tokenizer: The tokenizer name which will be loaded by the pipeline, default to the model's value

    Returns: Pipeline object

    r    LCannot convert because PyTorch is not installed. Please install torch first.r!   LCannot convert because TF is not installed. Please install tensorflow first.zLoading pipeline (model: z, tokenizer: ra   )rO   rx   rX   model_kwargs)r   	Exceptionr   rI   r   )r   rX   rO   rx   models_kwargss        r.   load_graph_from_argsr      sr      	 D!3!5fggD!2fgg	%eWM)A
FG M)ygtuur/   opsetr%   use_external_formatc                 b   t               st        d      ddl}ddlm} t        d|j                          |j                         5  t        | d      \  }}}}	t        | j                  |	|      \  }
} || j                  ||j                         |
||d|       ddd       y# 1 sw Y   yxY w)	a  
    Export a PyTorch backed pipeline to ONNX Intermediate Representation (IR

    Args:
        nlp: The pipeline to be exported
        opset: The actual version of the ONNX operator set to use
        output: Path where will be stored the generated ONNX model
        use_external_format: Split the model definition from its parameters to allow model bigger than 2GB

    Returns:

    r   r   N)exportzUsing framework PyTorch: r    T)frQ   r   r   do_constant_foldingopset_version)r   r   torch
torch.onnxr   rI   rB   no_gradr   rV   rO   as_posix)rW   r   r%   r   r   r   rQ   r   r   rP   rT   rS   s               r.   convert_pytorchr     s     fgg!	%e&7&7%8
9:	 
:FsD:Q7\<*<SYYP[*\'ZIIoo+%% $		
	
 
 
s   AB%%B.c           	         t               st        d      t        d       	 ddl}ddl}ddlm} t        d|j                  j                   d|        t        | d      \  }}}}	| j                  j                  |	j                         |	j                         D 
cg c]"  \  }
}|j                  j                  ||
	      $ }}
}|j                  j!                  | j                  |||j#                         
      \  }}yc c}}
w # t$        $ r-}t        d|j&                   d|j&                   d|       d}~ww xY w)av  
    Export a TensorFlow backed pipeline to ONNX Intermediate Representation (IR)

    Args:
        nlp: The pipeline to be exported
        opset: The actual version of the ONNX operator set to use
        output: Path where will be stored the generated ONNX model

    Notes: TensorFlow cannot export model bigger than 2GB due to internal constraint from TensorFlow

    r   zD/!\ Please note TensorFlow doesn't support exporting model > 2Gb /!\r   N)rB   zUsing framework TensorFlow: z, tf2onnx: r!   )rZ   )r   output_pathzCannot import z6 required to convert TF model to ONNX. Please install z first. )r   r   rI   
tensorflowtf2onnxrB   versionVERSIONr   rO   predictdatar|   
TensorSpecfrom_tensorconvert
from_kerasr   rD   rZ   )rW   r   r%   r!   r   t2ovrQ   r   r   rP   keyrk   input_signaturemodel_proto_es                   r.   convert_tensorflowr   &  s/    fgg	
RS
/,RZZ-?-?,@D6RS ;GsD:Q7\< 			&++&Z`ZfZfZhi;3PV2==44V#4Fii 33IIeAR 4 
Q j
  
QVVH$Z[\[a[aZbbjkljmn
 	

s*   A<D	 'D=D	 D	 		D?(D::D?c                    t        j                  dt               t        d|        t	        || ||fi |}|j
                  j                         s<t        d|j
                          t        |j
                  j                                nVt        t        |j
                  j                                     dkD  r't        d|j
                  j                          d      | dk(  rt        ||||       yt        |||       y)	a  
    Convert the pipeline object to the ONNX Intermediate Representation (IR) format

    Args:
        framework: The framework the pipeline is backed by ("pt" or "tf")
        model: The name of the model to load for the pipeline
        output: The path where the ONNX graph will be stored
        opset: The actual version of the ONNX operator set to use
        tokenizer: The name of the model to load for the pipeline, default to the model's name if not provided
        use_external_format:
            Split the model definition from its parameters to allow model bigger than 2GB (PyTorch only)
        pipeline_name: The kind of pipeline to instantiate (ner, question-answering, etc.)
        model_kwargs: Keyword arguments to be forwarded to the model constructor

    Returns:

    zoThe `transformers.convert_graph_to_onnx` package is deprecated and will be removed in version 5 of TransformerszONNX opset version set to: zCreating folder r   zFolder z" is not empty, aborting conversionr    N)warningswarnFutureWarningrI   r   r9   existsr   r   rh   r   r   r   r   )	rX   rO   r%   r   rx   r   r   r   rW   s	            r.   r   r   N  s    6 MM	
 
'w
/0 }i	
Z\
ZC==! 01'')*	WV]]++-.	/!	3'&--"8"8":!;;]^__ DUF,?@3v.r/   onnx_model_pathc                     ddl m}m} t        | d      } |       }|j	                         |_         || j	                         |      }t        d| d       t        d       |S )a>  
    Load the model at the specified path and let onnxruntime look at transformations on the graph to enable all the
    optimizations possible

    Args:
        onnx_model_path: filepath where the model binary description is stored

    Returns: Path where the optimized model binary description has been saved

    r   InferenceSessionSessionOptionsz
-optimizedz$Optimized model has been written at    : ✔zY/!\ Optimized model contains hardware specific operators which might not be portable. /!\)rA   r   r   r>   r   optimized_model_filepathrI   )r   r   r   opt_model_pathsess_optionr   s         r.   optimizer     sf     = 2/<PN "K+9+B+B+DK(113[AA	00@@V
WX	
ghr/   c                    ddl }ddl}ddlm} ddlm} ddlm} ddlm	} |j                  | j                               }t        |j                        t        d      k  rt        d        |       }|j                  |       t        |j                        t        d	      k  r' ||d
d
|j                   d
dd
dddt#        |            }	n& ||d
d
|j                   d
dd
dddt#        |            }	|	j%                          t'        | d      }
t        d|
 d       |j)                  |	j*                  j*                  |
j                                |
S )z
    Quantize the weights of the model from float32 to in8 to allow very efficient inference on modern CPU

    Args:
        onnx_model_path: Path to location the exported ONNX model is stored

    Returns: The Path generated for the quantized
    r   N)
ModelProto)QuantizationMode)ONNXQuantizer)IntegerOpsRegistryz1.5.0zpModels larger than 2GB will fail to quantize due to protobuf constraint.
Please upgrade to onnxruntime >= 1.5.0.z1.13.1FT)rO   per_channelreduce_rangemodestaticweight_qTypeinput_qTypetensors_rangenodes_to_quantizenodes_to_excludeop_types_to_quantize)rO   r   r   r   r   r   activation_qTyper   r   r   r   z
-quantizedz$Quantized model has been written at r   )onnxrA   onnx.onnx_pbr   onnxruntime.quantizationr   'onnxruntime.quantization.onnx_quantizerr   !onnxruntime.quantization.registryr   loadr   r   rB   rI   CopyFrom
IntegerOpsre   quantize_modelr>   
save_modelrO   )r   r   rA   r   r   r   r   
onnx_model
copy_model	quantizerquantized_model_paths              r.   quantizer     sO    '9ED ?3356JTw/6	
 J
# [$$%h7!!,,"!!%&8!9
	 "!,,""!!%&8!9
	  8V 
01E0FF\
]^OOIOO))+?+H+H+JKr/   pathc                     ddl m}m} ddlm} t        d|  d       	  |       } || j                         |dg      }t        d|  d	       y # |$ r}t        d
| d       Y d }~y d }~ww xY w)Nr   r   )RuntimeExceptionz"Checking ONNX model loading from: z ...CPUExecutionProvider)	providerszModel u    correctly loaded: ✔zError while loading the model u   : ✘)rA   r   r   +onnxruntime.capi.onnxruntime_pybind11_stater   rI   r   )r   r   r   r   onnx_optionsr   res          r.   verifyr     sz    <L	.tfD
9:I%'T]]_lG]F^_tfCDE I.rd2FGHHIs   0A A.A))A.__main__z'
====== Converting model to ONNX ======r!   aV  	 Using TensorFlow might not provide the same optimization level compared to PyTorch.
	 For TensorFlow users you can try optimizing the model directly through onnxruntime_tools.
	 For more information, please refer to the onnxruntime documentation:
		https://github.com/microsoft/onnxruntime/tree/master/onnxruntime/python/tools/transformers
z$
====== Optimizing ONNX model ======z+
====== Check exported ONNX model(s) ======optimized_outputquantized_outputz"Error while converting the model: rH   )N)NFr   )=r   argparser   osr   r   pathlibr   typingr   r   r	   r
   packaging.versionr   r   transformers.pipelinesr   r   transformers.tokenization_utilsr   transformers.utilsr   r   r   rC   r*   r   r)   r>   rF   rV   r   r   r+   rw   r   r   r   r   r   r   r0   parser
parse_argsargsr%   absoluterI   rX   rO   r   rx   r   r   r   check_loadinghasattrr   r   exitrv   r/   r.   <module>r      s(    #    . . , 5 9 O O
  %W~ 
 +$. +$\
]4 
]S 
]T 
]
G 
:28=:h =:3 =:5cDItUb9b3c =:B PTvv#&v/2v?G}vv>"
 "
# "
t "
RV "
J%
H %
S %
$ %
Z  $ %-////// // 	//
 }// // //dd t 2H d H t H V
I 
I z(*FD t{{#,,.DK/89NNJJKKJJNN$$MM	
 ==*+GH ~~%w 9: %-T[[$9D! %-T-B-B$CD! @A4;;t/0t,,-t/0t,,- 1 U h  21#67Qs   !DH> >I II 