
    PiZ                        d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlm	Z	m
Z
mZmZmZmZmZ d dlmZ d dlZd dlmZ d dlmZ  ed          Z	 d	Zd	Zd
ZdZdZdZdZdZddddeeeegZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ* G d de          Z+ G d  d!          Z,dGd#ed$e-d%e.d&efd'Z/	 dHd)eee-f         d*e.d+e.d&e
e-e	f         fd,Z0	 dGd-e
e-ej1        f         d.eee-ej2        j3        f                  d/e.fd0Z4	 dId2ee-ef         d3e-d&ede-f         fd4Z5dd5d6d#ee-ef         d7ee-ef         d8eee-                  d9e6d&df
d:Z7	 	 dJd7ed;ee-         d<e.d&ee         fd=Z8	 	 	 dKd7ed>ee-         d<e.d3e-d&ee         f
d?Z9d@eee-         e
e-e-f         f         dAee-ef         d7ee-ef         d<e.dBe.d&e:e         fdCZ;dDedEed&e.fdFZ<dS )L    N)Enum)Path)AnyDictIterableListOptionalTupleUnion)warn)	safe_open)
get_loggerDEBUGadapter_configadapter_modelzmodel.safetensors.index.jsonzpytorch_model.bin.index.jsonzmodel-{cpt_idx}-of-{num_shards}recipe_stateoriginal_repo_idz.ptz.pthz.bin.safetensorsadapter
epochs_runmax_steps_per_epochmodel	optimizerseedtotal_epochs	steps_run	rng_state
dataloaderc                       e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	eed	<   d
Z
eed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dS )	ModelTypea  ModelType is used by the checkpointer to distinguish between different model architectures.

    If you are adding a new model that follows a different format than those in the repo already,
    you can add a new ModelType to gate on weight conversion logic unique to that model.

    Attributes:
        GEMMA (str): Gemma family of models. See :func:`~torchtune.models.gemma.gemma`
        GEMMA2 (str): Gemma 2 family of models. See :func:`~torchtune.models.gemma2.gemma2`
        LLAMA2 (str): Llama2 family of models. See :func:`~torchtune.models.llama2.llama2`
        LLAMA3 (str): Llama3 family of models. See :func:`~torchtune.models.llama3.llama3`
        LLAMA3_2 (str): Llama3.2 family of models. See :func:`~torchtune.models.llama3_2.llama3_2`
        LLAMA3_VISION (str): LLama3 vision family of models. See :func:`~torchtune.models.llama3_2_vision.llama3_2_vision_decoder`
        MISTRAL (str): Mistral family of models. See :func:`~torchtune.models.mistral.mistral`
        PHI3_MINI (str): Phi-3 family of models. See :func:`~torchtune.models.phi3.phi3`
        PHI4 (str): Phi-4 family of models. See :func:`~torchtune.models.phi4.phi4`
        REWARD (str): A Llama2, Llama3, or Mistral model with a classification head projecting
            to a single class for reward modelling.
            See :func:`~torchtune.models.mistral.mistral_reward_7b` or :func:`~torchtune.models.llama2.llama2_reward_7b`
        QWEN2 (str): Qwen2 family of models. See :func:`~torchtune.models.qwen2.qwen2`
        CLIP_TEXT (str): CLIP text encoder. See :func:`~torchtune.models.clip.clip_text_encoder_large`
        T5_ENCODER (str): T5 text encoder. See :func:`~torchtune.models.t5.t5_v1_1_xxl_encoder`

    Example:
        >>> # Usage in a checkpointer class
        >>> def load_checkpoint(self, ...):
        >>>     ...
        >>>     if self._model_type == MY_NEW_MODEL:
        >>>         state_dict = my_custom_state_dict_mapping(state_dict)
    gemmaGEMMAgemma2GEMMA2llama2LLAMA2llama3LLAMA3llama3_2LLAMA3_2llama3_visionLLAMA3_VISIONmistralMISTRAL	phi3_mini	PHI3_MINIphi4PHI4rewardREWARDqwen2QWEN2	clip_text	CLIP_TEXT
t5_encoder
T5_ENCODERN)__name__
__module____qualname____doc__r"   str__annotations__r$   r&   r(   r*   r,   r.   r0   r2   r4   r6   r8   r:        {/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/torchtune/training/checkpointing/_utils.pyr    r    N   s          < E3FCFCFCHc(M3(((GS Is   D#FCE3 Is   "J"""""rB   r    c                   N    e Zd ZdZdedefdZededd fd            Zd Z	d	 Z
d
S )FormattedCheckpointFilesa  
    This class gives a more concise way to represent a list of filenames of the format ``file_{i}_of_{n_files}.pth``.

    Args:
        filename_format (str): Format string for the filename. Must have exactly two placeholders, e.g.
            ``file_{}_of_{}.pth``.
        max_filename (str): Maximum filename in the list. Should be a string representation of an integer,
            possibly with leading zeroes.
    filename_formatmax_filenamec                 J    || _         || _        |                                  d S N)rF   rG   _validate_filename_format)selfrF   rG   s      rC   __init__z!FormattedCheckpointFiles.__init__   s,    
  /(&&(((((rB   dreturnc                     d|vsd|vrt          d          t          |d         t                    s&t          dt          |d                    d           | |d         |d                   S )NrF   rG   zTMust pass 'filename_format' and 'max_filename' keys to generate checkpoint filenamesz+`max_filename` must be a string, but found z	 instead.)rF   rG   )
ValueError
isinstancer?   type)clsrM   s     rC   	from_dictz"FormattedCheckpointFiles.from_dict   s    A%%q)@)@f   !N+S11 	`d1^CT>U>U```   s/0>*
 
 
 	
rB   c                     d t          j                                        | j                  D             }t	          |          dk    rt          d          d S )Nc                 .    g | ]}|d          
|d          S    rA   ).0xs     rC   
<listcomp>zFFormattedCheckpointFiles._validate_filename_format.<locals>.<listcomp>   s0     !
 !
 !
t aDrB      z[Filename format string must have exactly two placeholders, e.g. 'file_{i}_of_{n_files}.pth')string	FormatterparserF   lenrP   )rK   n_format_placeholderss     rC   rJ   z2FormattedCheckpointFiles._validate_filename_format   sn    !
 !
%''--d.BCC!
 !
 !

 $%%**m   +*rB   c                 b     t           j                  } fdt          |          D             S )a  
        Builds a list of checkpoint filenames from the filename format and max filename.

        Returns:
            List[str]: List of checkpoint filenames.

        Example:
            >>> # Example usage
            >>> f = FormattedCheckpointFiles(filename_format="file_{}_of_{}.safetensors", max_filename="00003")
            >>> f.build_checkpoint_filenames()
            >>> ['file_00001_of_00003.safetensors', 'file_00002_of_00003.safetensors', 'file_00003_of_00003.safetensors']
        c           	          g | ]W}j                             t          |d z                                 t	          j                            j                  XS rW   )rF   formatr?   zfillr`   rG   )rY   irK   s     rC   r[   zGFormattedCheckpointFiles.build_checkpoint_filenames.<locals>.<listcomp>   sj     
 
 

 	  ''AE

  T%6!7!788! 
 
 
rB   )intrG   range)rK   	num_filess   ` rC   build_checkpoint_filenamesz3FormattedCheckpointFiles.build_checkpoint_filenames   sJ     )**	
 
 
 

 9%%
 
 
 	
rB   N)r;   r<   r=   r>   r?   rL   classmethoddictrT   rJ   rj   rA   rB   rC   rE   rE   |   s         )) ) ) ) ) 
$ 
#= 
 
 
 [
	 	 	
 
 
 
 
rB   rE   F	input_dirfilename
missing_okrN   c                     |                                  st          |  d          t          j        | |          }|s*|                                st          d| d|  d          |S )a  
    Utility to recover and validate the path for a given file within a given directory.

    Args:
        input_dir (Path): Directory containing the file
        filename (str): Name of the file
        missing_ok (bool): Whether to raise an error if the file is missing.

    Returns:
        Path: Path to the file

    Raises:
        ValueError: If the file is missing and missing_ok is False.
    z is not a valid directory.zNo file with name: z
 found in .)is_dirrP   r   joinpathis_file)rm   rn   ro   	file_paths       rC   get_pathrv      s      CIAAABBBi22I  Qi//11 QOxOO9OOOPPPrB   Tcheckpoint_pathweights_onlymmapc                    	 t          |                               d          rdnd}|r_i }t          | dd          5 }|                                D ]}|                    |          ||<   	 ddd           n# 1 swxY w Y   |}n%t          j        t          |           d||          }n&# t          $ r}t          d	|  d
          |d}~ww xY w|S )aW  
    Utility to load a checkpoint file onto CPU in a safe manner. Provides separate handling for
    safetensors files.

    Args:
        checkpoint_path (Union[Path, str]): Path to the checkpoint file.
        weights_only (bool): Whether to load only tensors, primitive types, and dictionaries
            (passthrough to torch.load). Default: True
        mmap (bool): Whether to mmap from disk into CPU memory. Default: True

    Returns:
        Dict[str, Any]: State dict from the checkpoint file.

    Raises:
        ValueError: If the checkpoint file is not found or cannot be loaded.
    r   TFptcpu)	frameworkdeviceN)map_locationry   rx   zUnable to load checkpoint from z. )	r?   endswithr   keys
get_tensortorchload	ExceptionrP   )	rw   rx   ry   is_safetensors_fileresultfk
state_dictes	            rC   safe_torch_loadr      sT   &W ((11.AALDDu 	  	F?d5III 0Q 0 0A !QF1II00 0 0 0 0 0 0 0 0 0 0 0 0 0 0  JJO$$")	  J  W W WN?NNNOOUVVWs:   <B/ 0A;/B/ ;A??B/ A?+B/ /
C9CCr   model_named_parametersforce_overridec                 :   t          |                              dd          }d| vrt          d          |t          d          d| v r$t          d           |                     d           | d         j        d         |j        d         k    s|r|| d<   dS dS )af  
    Validates the state dict for checkpoint loading for a classifier model.
    To be used prior to a call to ``model.load_state_dict(state_dict)``.
    This function will overwrite the ``output.weight`` in the state-dict
    to be loaded with the ``output.weight`` in the model if the shapes
    for the ``output.weight`` do not match. You may also wish to override this behaviour,
    for example, if ``num_classes`` for your checkpoint and model are the same.

    Concretely, when fine-tuning a classifier model from the checkpoint of a base language model
    which has ``output.weight`` of shape ``[vocab_dim, embed_dim]``, we overwrite
    the ``output.weight`` in the state-dict to be loaded with the randomly initialized
    ``[num_classes, embed_dim]`` weight in the model. This is done in-place.

    Args:
        state_dict (Dict[str, torch.Tensor]): state dict to be loaded into the classifier model.
        model_named_parameters (Iterable[Tuple[str, torch.nn.Parameter]]): model named parameters
            from ``model.named_parameters()``.
        force_override (bool): Whether to replace ``output.weight`` in ``state_dict`` with the model's
            ``output.weight``, even if the shapes match.
    Notes:
        - ``output.bias`` will be ignored if present in ``state_dict``
        - This function will always replace the ``output.weight`` in ``state_dict``,
            if ``output.weight != model.output.weight``.

    Raises:
        AssertionError:
            If ``state_dict`` does not contain ``output.weight``, **or**
            if ``model_named_parameters`` does not contain ``output.weight``.

    zoutput.weightNz:Expected output.weight in state_dict, but it wasn't found.zFExpected output.weight in model_named_parameters, but it wasn't found.zoutput.biasz8Found output.bias in state dict - this will not be used!r   )rl   getAssertionErrorr   popshape)r   r   r   output_weights       rC    update_state_dict_for_classifierr     s    F /0044_dKKMj((H
 
 	
 T
 
 	
 
""GHHH}%%%/"(+}/B1/EEEE&3
?### FErB   ^epoch_(\d+)dirpatternc                 8   d }g }t          j        |          }t          j        |           D ]R}|                    |          }|r9t          |                    d                    }|                    ||f           S|rt          |d           d         }|S )NrX   c                     | d         S )NrX   rA   )rZ   s    rC   <lambda>z)get_largest_iter_folder.<locals>.<lambda>L  s
    ad rB   )keyr   )	recompileoslistdirmatchrg   groupappendmax)r   r   latest_epoch_folderiter_foldersregexfnamer   iter_numbers           rC   get_largest_iter_folderr   :  s     LJwE C 6 6E"" 	6ekk!nn--K 4555  G!,NNCCCAFrB   d   )ignore_suffixesmax_file_size_mb
output_dirr   r   c                   |dz  dz  }t          j        |           D ]X\  }}}d |D             |dd<   t           j                            ||           }t           j                            ||          }	t          j        |	d           |D ]                    d          r|rt          fd|D                       r6t           j                            |          }
t           j                            |	          }t           j                            |
          |k    rt          d|
 d	| d
| d           t           j        
                    |          st          j        |
|           ZdS )a  
    Copies files from the input directory to the output directory, preserving the directory structure.

    This function will skip copying files that already exist in the output directory or have specific suffixes.
    It will also skip folders and files that start with '.'. E.g. ".cache/" and ".git".

    Args:
        input_dir (Union[str, Path]): The path to the input directory containing files to be copied.
        output_dir (Union[str, Path]): The path to the output directory where files should be copied.
        ignore_suffixes (Optional[List[str]]): A list of file suffixes to exclude from copying.
          Defaults to ['.pt', '.bin', '.safetensors'] if not provided.
        max_file_size_mb (int): The maximum file size in megabytes to copy. Defaults to 100 MB.
    Returns:
        None
    Example:
    >>> copy_files('path/to/input_dir', 'path/to/output_dir')

    This will copy all files from 'path/to/input_dir' to 'path/to/output_dir', except those that
    already exist in the destination or have the specified suffixes.
    i   c                 <    g | ]}|                     d           |S )rq   )
startswith)rY   rM   s     rC   r[   zcopy_files.<locals>.<listcomp>r  s)    <<<!,,s*;*;<1<<<rB   NT)exist_okrq   c              3   B   K   | ]}                     |          V  d S rI   )r   )rY   suffixfiles     rC   	<genexpr>zcopy_files.<locals>.<genexpr>  s@       ' '*0f%%' ' ' ' ' 'rB   zSkipping copying z to z! as it exceeds the size limit of z MiB.)r   walkpathrelpathjoinmakedirsr   anygetsizeprintexistsshutilcopy2)rm   r   r   r   max_file_sizerootdirsfilesrelative_pathdest_dirsrc_file	dest_filer   s               @rC   
copy_filesr   R  s   8 %t+d2MWY// #2 #2dE =<d<<<QQQ i887<<
M:: 	Ht,,,, 	2 	2Ds##   3 ' ' ' '4C' ' ' $ $  w||D$//HXt44I wx((=88zzzjzzcszzz    7>>),, 2Xy111/	22 FrB   recipe_checkpointshould_load_recipe_statec                    |sdS d}|r!t           j                            | |          }n&t           j                            | t          d          }|rt           j                            |          st          d          t          |          S )a  
    If recipe_checkpoint is None, look for recipe_state.pt in {output_dir}/{RECIPE_STATE_DIRNAME}/recipe_state.pt.
    This is to make it easier to resume from a previous run, without having to specify the recipe_checkpoint.

    Args:
        output_dir (Path): Directory containing the recipe checkpoint.
        recipe_checkpoint (Optional[str]): Name of the recipe checkpoint file. Defaults to None.
        should_load_recipe_state (bool): Whether to load the recipe state from the checkpoint.
    Returns:
        Optional[Path]: Path to the recipe checkpoint file if should_load_recipe_state is True, otherwise None.
    Raises:
        ValueError: If should_load_recipe_state is True and the recipe checkpoint file is missing.
    Nzrecipe_state.ptzMIf should_load_recipe_state is True, recipe_checkpoint file must be provided.)r   r   r   RECIPE_STATE_DIRNAMEr   rP   r   )r   r   r   recipe_checkpoint_paths       rC   get_recipe_checkpoint_pathr     s    $ $ t! 
!#j:K!L!L!#,.?"
 "

 " 
8N)O)O 
[
 
 	
 &'''rB   adapter_checkpointc                     |sdS d}|r!t           j                            | |          }nSt          | |          }t           j                            | |d          }t           j                            |          r|}|rt          |          ndS )a  
    If adapter_checkpoint is None, look for it in {output_dir}/epoch_{latest_epoch}/adapter_model.pt.
    This is to make it easier to resume from a previous run, without having to specify the adapter_checkpoint.

    Args:
        output_dir (Path): Directory containing the adapter checkpoint.
        adapter_checkpoint (Optional[str]): Name of the adapter checkpoint file. Defaults to None.
        should_load_recipe_state (bool): Whether to load the recipe state from checkpoint.
        pattern (str): Regex pattern to match the epoch folder. Defaults to "epoch_(\d+)".

    Returns:
        Optional[Path]: Path to the adapter checkpoint file, or None if not applicable.
    N)r   zadapter_model.pt)r   r   r   r   r   r   )r   r   r   r   adapter_checkpoint_pathlargest_iter_folder!tentative_adapter_checkpoint_paths          rC   get_adapter_checkpoint_pathr     s    & $ t" H"$',,z;M"N"N 6j'RRR,.GLL+-?-
 -
) 7>>;<< 	H&G#,CM4'(((MrB   checkpoint_filescheckpoint_dirhas_adapter_checkpointc                 N   	 ddt           t          t                            dt          t                   dt          t                   fd}t          | t                    s.t                              |           }|                                } |s|}n|s|}n|} || |d          }|S )a!  
    Returns Paths to model checkpoint files, handling resuming from checkpoint, file formating and checking
    if the files exists.

    If resuming from checkpoint, the checkpoint files are loaded from the output directory. Otherwise,
    they are loaded from the checkpoint directory.

    If checkpoint_fiels is a dictionary, it is converted to a list of formatted checkpoint filenames.

    Args:
        checkpoint_files (Union[List[str], Dict[str, str]]): List or dictionary of checkpoint file names.
            If a dictionary with keys ["filename_format", "max_filename"] is provided,
            it is converted to a list of formatted checkpoint filenames.
        checkpoint_dir (Union[str, Path]): Directory containing the checkpoint files.
        output_dir (Union[str, Path]): Directory to use when resuming from a checkpoint.
        should_load_recipe_state (bool): Whether to resume from a checkpoint.
        has_adapter_checkpoint (bool): Indicates if there is an adapter checkpoint.
    Returns:
        list[Path]: Sorted list of paths to the checkpoint files.
    Example:
        >>> checkpoint_files = ["model-00001-of-00002.safetensors", "model-00002-of-00002.safetensors"]
        >>> checkpoint_dir = "/path/to/checkpoints"
        >>> output_dir = "/path/to/output"
        >>> should_load_recipe_state = True
        >>> has_adapter_checkpoint = False
        >>> paths = get_model_checkpoint_path(
        ...     checkpoint_files,
        ...     checkpoint_dir,
        ...     output_dir,
        ...     should_load_recipe_state,
        ...     has_adapter_checkpoint
        ... )
        >>> print(paths)
        [PosixPath('/path/to/output/{largest_epoch}/model-00001-of-00002.safetensors'),
         PosixPath('/path/to/output/{largest_epoch}/model-00002-of-00002.safetensors')]
    Fr   rm   rN   c                 z    g }| D ](}t          |||          }|                    |           )t          |          S )zR
        Validates that the checkpoint files exist and sorts based on ID.
        )rv   r   sorted)r   rm   ro   checkpoint_pathsr   rw   s         rC   validate_checkpoint_filesz<get_model_checkpoint_path.<locals>.validate_checkpoint_files  sP     (*! 	5 	5A&y!Z@@O##O4444&'''rB   )rm   ro   F)	r   r   r?   r	   r   rQ   rE   rT   rj   )	r   r   r   r   r   r   formatted_checkpoint_filesrm   r   s	            rC   get_model_checkpoint_pathr     s    ^ ( (S	*(D>( 
d	( ( ( (. &-- S%=%G%G&
 &
" 6PPRR $ #"		 $ 	#		 #	00   rB   ckpt_dirout_dirc                     |                                  }|                                 }||k    s	||j        v rt          d| d|d          dS )z
    Checks that the output directory is not equal to or a subdirectory of the checkpoint directory.
    This is necessary to avoid making copies of copies when geting config files from ckpt_dir.
    ziThe output directory cannot be the same as or a subdirectory of the checkpoint directory. Found ckpt_dir=z and out_dir=rq   T)resolveparentsrP   )r   r   	_ckpt_dir_out_dirs       rC   check_outdir_not_in_ckptdirr   H  s{       ""I  H 9	X-= = =11 1%,1 1 1
 
 	

 4rB   r   )TT)r   )NF)NFr   )=r   r   r   r]   enumr   pathlibr   typingr   r   r   r   r	   r
   r   warningsr   r   safetensorsr   torchtune.utils._loggingr   loggerADAPTER_CONFIGADAPTER_CONFIG_FNAMEADAPTER_MODEL_FNAMESAFETENSOR_INDEX_FNAMETORCH_INDEX_FNAMESHARD_FNAMEr   REPO_ID_FNAMESUFFIXES_TO_NOT_COPYADAPTER_KEY
EPOCHS_KEYMAX_STEPS_KEY	MODEL_KEYOPT_KEYSEED_KEYTOTAL_EPOCHS_KEY	STEPS_KEYRNG_KEYDATALOADER_KEYr    rE   r?   boolrv   r   Tensornn	Parameterr   r   rg   r   r   r   listr   r   rA   rB   rC   <module>r     s   
			 				               D D D D D D D D D D D D D D D D D D        ! ! ! ! ! ! / / / / / /	G		
 " ( % 7 2  0%  #	

	   
%	
 "  	  +# +# +# +# +# +# +# +#\B
 B
 B
 B
 B
 B
 B
 B
J    $    6 PT( (49%(59(HL(	#s(^( ( ( (\ !04 04S%,&'04$U30B+B%CD04 04 04 04 04j +: 	sDy	$'
49   8 ,0B B BS$YBc4i B d3i(	B
 B 
B B B BN (,%*#( #(#(}#( ##( d^	#( #( #( #(P )-%*"	%N %N%N %N #%N 	%N
 d^%N %N %N %NP`DItCH~56`#t)$` c4i ` #	`
 !` 
$Z` ` ` `F$  $      rB   