U
    4Af3R                     @   s  d dl Z d dlZd dlmZmZ d dlmZ d dlZd dl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mZmZmZ ddlmZmZmZ dd	lmZ e rd dlZej j!"d
 e rd dl#Z#e rd dl$m%Z% dZ&edddZ'G dd deZ(dS )    N)ArgumentParser	Namespace)import_module)version   )FEATURE_EXTRACTOR_MAPPINGIMAGE_PROCESSOR_MAPPINGPROCESSOR_MAPPINGTOKENIZER_MAPPING
AutoConfigAutoFeatureExtractorAutoImageProcessorAutoProcessorAutoTokenizeris_datasets_availableis_tf_availableis_torch_available)TF2_WEIGHTS_INDEX_NAMETF2_WEIGHTS_NAMElogging   )BaseTransformersCLICommandF)load_datasetg-C6
?argsc              	   C   s&   t | j| j| j| j| j| j| j| jS )z~
    Factory function used to convert a model PyTorch checkpoint in a TensorFlow 2 checkpoint.

    Returns: ServeCommand
    )	PTtoTFCommand
model_name	local_dir	max_errornew_weightsno_prpushextra_commit_descriptionoverride_model_classr    r$   B/tmp/pip-unpacked-wheel-zw5xktn0/transformers/commands/pt_to_tf.pyconvert_command_factory9   s    r&   c                	   @   sV   e Zd ZeedddZedd Zeeee	e	e	eedddZ
d	d
 Zdd ZdS )r   )parserc                 C   s   | j ddd}|jdtddd |jdtd	d
d |jdttdt dd |jdddd |jdddd |jdddd |jdtd	dd |jdtddd |jtd dS )z
        Register this command to argparse so it's available for the transformer-cli

        Args:
            parser: Root parser to register command-specific arguments
        zpt-to-tfzCLI tool to run convert a transformers model from a PyTorch checkpoint to a TensorFlow checkpoint. Can also be used to validate existing weights without opening PRs, with --no-pr.)helpz--model-nameTzAThe model name, including owner/organization, as seen on the hub.)typerequiredr(   z--local-dir zOOptional local directory of the model repository. Defaults to /tmp/{model_name})r)   defaultr(   z--max-errorz%Maximum error tolerance. Defaults to z4. This flag should be avoided, use at your own risk.z--new-weights
store_truezKOptional flag to create new TensorFlow weights, even if they already exist.)actionr(   z--no-prz6Optional flag to NOT open a PR with converted weights.z--pushzKOptional flag to push the weights directly to `main` (requires permissions)z--extra-commit-descriptionzXOptional additional commit description to use when opening a PR (e.g. to tag the owner).z--override-model-classNzIf you think you know better than the auto-detector, you can specify the model class here. Can be either an AutoModel class or a specific model class like BertForSequenceClassification.)func)
add_parseradd_argumentstrfloat	MAX_ERRORset_defaultsr&   )r'   Ztrain_parserr$   r$   r%   register_subcommandL   sd    
  z!PTtoTFCommand.register_subcommandc                    sP   t |  }t | }||kr6td| d| dd fdd	  | |i S )zr
        Compares the TensorFlow and PyTorch outputs, returning a dictionary with all tensor differences.
        zAThe model outputs have different attributes, aborting. (Pytorch: z, TensorFlow: )r+   c           
         s   t | tjr2tt|  |  }|||< n`|}t| D ]R\}}t |trj|| }|| }	| | }n|d| d }|| }	 ||	||}q>|S )N[])	
isinstancetorchZTensornpmaxabsnumpy	enumerater2   )
Zpt_outZtf_outZdifferences	attr_nameZtensor_difference	root_nameiZpt_itembranch_nameZtf_item_find_pt_tf_differencesr$   r%   rF      s    


zEPTtoTFCommand.find_pt_tf_differences.<locals>._find_pt_tf_differences)r+   )setkeys
ValueError)
pt_outputs
tf_outputsZpt_out_attrsZtf_out_attrsr$   rE   r%   find_pt_tf_differences   s    z$PTtoTFCommand.find_pt_tf_differences)r   r   r   r   r    r!   r"   r#   c	           
      G   sR   t d| _|| _|r|ntjd|| _|| _|| _	|| _
|| _|| _|| _d S )Nztransformers-cli/pt_to_tfz/tmp)r   Z
get_logger_logger_model_nameospathjoin
_local_dir
_max_error_new_weights_no_pr_push_extra_commit_description_override_model_class)
selfr   r   r   r   r    r!   r"   r#   r   r$   r$   r%   __init__   s    zPTtoTFCommand.__init__c                 C   s6  dd }t |j}|tkrHt| j}|tkr|jjdkr|jj	|j_nd|t
kr^t| j}nN|tkrtt| j}n8|tkrt| j}|jdkr|j	|_ntd| dtt|jj }i }d|kr|ddgd	d	d
 d|krtdddddd d }	|d|	i d|krxt|jj}
d|
krb|
d j}|dk	r\|dk	r\|}nd	}nd	}|| |d d|kr|| d	d |f |ddi}|f |ddi}|jst|drt|dsd|kr.tjdgdggtd|jjpd  }|dt !|i |dt"#|i ||fS )!zQ
        Returns the right inputs for the model, based on its signature.
        c                  S   s@   t dddd} | dtdd d d }dd	 |D }|S )
Nz)hf-internal-testing/librispeech_asr_dummycleanZ
validationsplitidr   audioc                 S   s   g | ]}|d  qS )arrayr$   ).0xr$   r$   r%   
<listcomp>   s     zFPTtoTFCommand.get_inputs.<locals>._get_audio_input.<locals>.<listcomp>)r   sortselectrange)ZdsZspeech_samplesZraw_samplesr$   r$   r%   _get_audio_input   s     z2PTtoTFCommand.get_inputs.<locals>._get_audio_inputNz1Unknown data processing type (model config type: r7   Z	input_idsz	Hi there!z@I am a batch with more than one row and different input lengths.T)textpaddingZ
truncationZpixel_valueszuoft-cs/cifar10Z
plain_texttestr\   r   imgZimagesZinput_featuresri   F)r_   ri   Zinput_valuesZreturn_tensorspttfencoderdecoderdecoder_input_idsr   )Zdtyper   )$r)   configr	   r   from_pretrainedrR   r
   	tokenizerZ	pad_tokenZ	eos_tokenr   r   r   r   r   rI   rG   inspect	signatureZforward
parametersrH   updater   Zfeature_extractorr,   Zis_encoder_decoderhasattrr<   ZasarrayintZdecoder_start_token_idr;   Ztensorrm   Zconvert_to_tensor)rY   pt_modeltf_dummy_inputsrq   rg   Zmodel_config_class	processorZmodel_forward_signatureZprocessor_inputsZsample_imagesZfeature_extractor_signatureZdefault_strategyZpadding_strategypt_inputtf_inputrp   r$   r$   r%   
get_inputs   sh    







$zPTtoTFCommand.get_inputsc           !   	      s   j d ttjtdk r,tdnddlm}m} ddl	m
} | j jd}t j}|j} jd k	r  jdr jd	d  g}n jg}zttd
|d }W n& tk
r   td j dY nX zttd
d|d  }W n( tk
r   td j dY nX n|d krTttd
d}ttd
d} j d nt|dkrrtd| d j d|d   ttd
|d }zttd
d|d  }W n* tk
r   td|d  dY nX ||}	|	j}
~	| j}|   ||
|\}}t  |f |ddi}W 5 Q R X ~|j jdd}	|	f |ddd} ||}dd | D }dd | D }t|dkr|d k	rtd| d |rt|  nd!}t|  }| j!ks| j!krRtd"d# j! d$ d%" fd&d'| D  d( j! d$ d%" fd)d'| D  t#j$" jt%}t#j$" jt&}t#j$'|st#j$'|r j(r|	) j ~	| j}|f |ddi} ||}d*d | D }d+d | D }t|dkr|d k	rtd| d |r,t|  nd!}t|  }| j!ksT| j!krtd,d# j! d$ d%" fd-d'| D  d( j! d$ d%" fd.d'| D   j(rd/nd0} j*r |j+dd1 |,| |j-dd2  j d3 j  n j.s j d4 d5|d6d7|d6d8|d6d9|d6d:	} j!t/krX|d; j! d<7 } j0rn|d= j0 7 }t#j$'|r|t&|d>g}t1j2j34 jd? D ] }||t#j$5||d>g7 }qn|t%|d>g}| j|||d@ddAj6}  j dB|   d S )CNak  

Converting PyTorch weights to TensorFlow is deprecated and will be removed in v4.43. Instead, we recommend that you convert PyTorch weights to Safetensors, an improved format that can be loaded by any framework, including TensorFlow. For more information, please see the Safetensors conversion guide: https://huggingface.co/docs/safetensors/en/convert-weights

z0.9.0zrThe huggingface_hub version must be >= 0.9.0 to use this command. Please update your huggingface_hub installation.r   )
Repositorycreate_commit)CommitOperationAdd)r   Z
clone_fromZTFr   ZtransformerszModel class z not found in transformers.zTF model class TFZ	AutoModelZTFAutoModelz5No detected architecture, using AutoModel/TFAutoModelr   zAMore than one architecture was found, aborting. (architectures = r7   zDetected architecture: zThe TensorFlow equivalent of z doesn't exist in transformers.output_hidden_statesT)Zfrom_ptF)r   Ztrainingc                 S   s   i | ]\}}d |kr||qS hiddenr$   ra   kvr$   r$   r%   
<dictcomp>U  s       z%PTtoTFCommand.run.<locals>.<dictcomp>c                 S   s   i | ]\}}d |kr||qS r   r$   r   r$   r$   r%   r   V  s       z;Something went wrong -- the config file has architectures (zF), but no model head output was found. All outputs start with 'hidden'g        zOThe cross-loaded TensorFlow model has different outputs, something went wrong!
z9
List of maximum output differences above the threshold (z):

c                    s*   g | ]"\}}| j kr| d |dqS z: .3erS   r   rY   r$   r%   rc   b  s     
 z%PTtoTFCommand.run.<locals>.<listcomp>z@

List of maximum hidden layer differences above the threshold (c                    s*   g | ]"\}}| j kr| d |dqS r   r   r   r   r$   r%   rc   d  s     
 c                 S   s   i | ]\}}d |kr||qS r   r$   r   r$   r$   r%   r   r  s       c                 S   s   i | ]\}}d |kr||qS r   r$   r   r$   r$   r%   r   s  s       zLThe converted TensorFlow model has different outputs, something went wrong!
c                    s*   g | ]"\}}| j kr| d |dqS r   r   r   r   r$   r%   rc     s     
 c                    s*   g | ]"\}}| j kr| d |dqS r   r   r   r   r$   r%   rc     s     
 zUpdate TF weightszAdd TF weights)Zauto_lfs_track)blockingzTF weights pushed into z&Uploading the weights into a new PR...a  Model converted by the [`transformers`' `pt_to_tf` CLI](https://github.com/huggingface/transformers/blob/main/src/transformers/commands/pt_to_tf.py). All converted model outputs and hidden layers were validated against its PyTorch counterpart.

Maximum crossload output difference=r   z,; Maximum crossload hidden layer difference=z';
Maximum conversion output difference=z-; Maximum conversion hidden layer difference=z;
zB

CAUTION: The maximum admissible error was manually increased to !z

)Zpath_in_repoZpath_or_fileobjz/tf_model-*.h5model)Zrepo_id
operationscommit_messageZcommit_descriptionZ	repo_typeZ	create_przPR open in )7rM   warningr   parsehuggingface_hub__version__ImportErrorr   r   Zhuggingface_hub._commit_apir   rR   rN   r   rr   architecturesrX   
startswithgetattrr   AttributeErrorrI   lenZfrom_configZdummy_inputsevalr   r;   Zno_gradrL   itemsr=   valuesrS   rQ   rO   rP   r   r   existsrT   Zsave_pretrainedrV   Zgit_addZ
git_commitZgit_pushrU   r4   rW   rm   ioZgfileglobbasenameZpr_url)!rY   r   r   r   reporq   r   Zpt_classZtf_classZtf_from_pt_modelr{   rz   r}   r~   rJ   Ztf_from_pt_outputsZcrossload_differencesZoutput_differencesZhidden_differencesZmax_crossload_output_diffZmax_crossload_hidden_diffZtf_weights_pathZtf_weights_index_pathZtf_modelrK   Zconversion_differencesZmax_conversion_output_diffZmax_conversion_hidden_diffr   Zcommit_descritionr   Z
shard_pathZ
hub_pr_urlr$   r   r%   run  s   



	$

$	
zPTtoTFCommand.runN)__name__
__module____qualname__staticmethodr   r6   rL   r2   r3   boolrZ   r   r   r$   r$   r$   r%   r   K   s   >
'Fr   ))rt   rO   argparser   r   	importlibr   r   r?   r<   	packagingr   r+   r   r   r	   r
   r   r   r   r   r   r   r   r   utilsr   r   r   r   Z
tensorflowrm   rq   ZexperimentalZ enable_tensor_float_32_executionr;   Zdatasetsr   r4   r&   r   r$   r$   r$   r%   <module>   s&   8