o
    ~ri4B                  
   @   s   d 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	 e
eZG dd dejZG d	d
 d
Zdd ZG dd dZ				ddedB dedB dedB dedB fddZdd ZdS )zACollection of utils to be used by backbones and their components.    N)repo_exists   )logging)maybe_install_capturing_hooksc                   @   s   e Zd ZdZdZdS )BackboneTypetimmtransformersN)__name__
__module____qualname__TIMMTRANSFORMERS r   r   i/lsinfo/ai/hellotax_ai/llm_service/venv_embed/lib/python3.10/site-packages/transformers/backbone_utils.pyr      s    r   c                       s   e Zd ZdZdedB dedB fddZdd Zed	d
 Zej	dee
 fdd
Zedd Zej	deedf ee B fddZ fddZ  ZS )BackboneConfigMixinzv
    A Mixin to support handling the `out_features` and `out_indices` attributes for the backbone configurations.
    out_featuresNout_indicesc                    s   | _ t|trt|n| _    j  j}}|du r1|du r1t jd g} jd g}n#|du rC|durC fdd|D }n|du rT|durT fdd|D }|| _  _   dS )ap  
        Sets output indices and features to new values and aligns them with the given `stage_names`.
        If one of the inputs is not given, find the corresponding `out_features` or `out_indices`
        for the given `stage_names`.

        Args:
            out_features (`list[str]`, *optional*):
                The names of the features for the backbone to output. Defaults to `config._out_features` if not provided.
            out_indices (`list[int]` or `tuple[int]`, *optional*):
                The indices of the features for the backbone to output. Defaults to `config._out_indices` if not provided.
        Nr   c                    s   g | ]} j |qS r   )stage_namesindex).0layerselfr   r   
<listcomp>D   s    zJBackboneConfigMixin.set_output_features_output_indices.<locals>.<listcomp>c                       g | ]} j | qS r   r   r   idxr   r   r   r   F       )_out_features
isinstancetuplelist_out_indicesverify_out_features_out_indiceslenr   )r   r   r   r   r   r   "set_output_features_output_indices(   s   z6BackboneConfigMixin.set_output_features_output_indicesc                    s,   j du r	td jduret jtfstdt j t fdd jD r7td j  d j t jtt jkrKtd j  j fd	d
 j D  }kretd| d j  j	durt j	tsztdt j	 t
 fdd j	D }t fdd|D rtd j  d j	 t|tt|krd j	 }|| j	krd| dnd7 }t||t
t|krdd
 tt| j	dd dD }td| d j	  jdur j	durt jt j	krtd j fdd
 j	D krtddS dS dS )z_
        Verify that out_indices and out_features are valid for the given stage_names.
        Nz2Stage_names must be set for transformers backbonesz out_features must be a list got c                 3   s    | ]}| j vV  qd S Nr   r   featr   r   r   	<genexpr>V   s    zFBackboneConfigMixin.verify_out_features_out_indices.<locals>.<genexpr>z.out_features must be a subset of stage_names: z got z2out_features must not contain any duplicates, got c                    s   g | ]	}| j v r|qS r   r    r)   r   r   r   r   ]   s    zGBackboneConfigMixin.verify_out_features_out_indices.<locals>.<listcomp>z@out_features must be in the same order as stage_names, expected z out_indices must be a list, got c                 3   s*    | ]}|d k r|t  j n|V  qdS )r   N)r&   r   r   r   r   r   r+   g   s   ( c                 3   s&    | ]}|t t jvr|V  qd S r(   )ranger&   r   r   r   r   r   r+   h   s   $ z2out_indices must be valid indices for stage_names z, got z1out_indices must not contain any duplicates, got z(equivalent to z)) c                 S   s   g | ]\}}|qS r   r   )r   _r   r   r   r   r   q   s    c                 S   s   | d S )Nr   r   )xr   r   r   <lambda>r   s    zEBackboneConfigMixin.verify_out_features_out_indices.<locals>.<lambda>)keyz?out_indices must be in the same order as stage_names, expected zHout_features and out_indices should have the same length if both are setc                    r   r   r   r   r   r   r   r   {   r   zQout_features and out_indices should correspond to the same stages if both are set)r   
ValueErrorr    r!   r#   typeanyr&   setr$   r"   sortedzip)r   sorted_featspositive_indicesmsgsorted_negativer   r   r   r%   L   sV   


z3BackboneConfigMixin.verify_out_features_out_indicesc                 C      | j S r(   r,   r   r   r   r   r   ~      z BackboneConfigMixin.out_featuresc                 C   s   | j |dd dS )
        Set the out_features attribute. This will also update the out_indices attribute to match the new out_features.
        Nr   r   )r'   r   r   r   r   r   r      s   c                 C   r=   r(   )r$   r   r   r   r   r      r>   zBackboneConfigMixin.out_indices.c                 C   s&   |durt |n|}| jd|d dS )
        Set the out_indices attribute. This will also update the out_features attribute to match the new out_indices.
        Nr@   )r#   r'   r   r   r   r   r   r      s   c                    s.   t   }|dd|d< |dd|d< |S )z
        Serializes this instance to a Python dictionary. Override the default `to_dict()` from `PreTrainedConfig` to
        include the `out_features` and `out_indices` attributes.
        r    Nr   r$   r   )superto_dictpop)r   output	__class__r   r   rE      s   
zBackboneConfigMixin.to_dict)r	   r
   r   __doc__r#   r'   r%   propertyr   setterstrr   r"   intrE   __classcell__r   r   rH   r   r   #   s"    
$2

 r   c                    s   t   fdd}|S )ak  
    Wrapper to filer out `hidden_states` as backbones tend to always use them to get their feature maps, i.e.
    they also always output `hidden_states`. This controls for user-defined behavior again.

    NOTE: We assume a `can_return_tuple` decorator to be applied before so that we always expect a dict like
          object to remove the hidden states.
    c                    sX   | dt| jdd} | g|R i |}|s*dd | D }t|di |}|S )Noutput_hidden_statesFc                 S   s   i | ]\}}|d vr||qS )hidden_statesr   r   kvr   r   r   
<dictcomp>       z@filter_output_hidden_states.<locals>.wrapper.<locals>.<dictcomp>r   )getgetattrconfigitemsr4   )r   argskwargsrP   rG   filtered_output_dataforward_functionr   r   wrapper   s   z,filter_output_hidden_states.<locals>.wrapper)	functoolswraps)r_   r`   r   r^   r   filter_output_hidden_states   s   	rc   c                       s   e Zd ZU dZedB ed< dZeed< d! fddZ fdd	Z	d!d
dZ
d!ddZedd Zejdee fddZedd Zejdee ee B fddZedd Zedd Zdd Z			d"dedB dedB dedB fdd Z  ZS )#BackboneMixinNbackbone_typeThas_attentionsreturnc                    s~   t  j|i | |dd}|durtj| _ntj| _| jtjkr*| j|d dS | jtjkr6|   dS t	d| j d)z
        Method to initialize the backbone. This method is called by the constructor of the base class after the
        pretrained model weights have been loaded.
        timm_backboneN)backbonezbackbone_type z not supported.)
rD   __init__rF   r   r   re   r   _init_timm_backbone_init_transformers_backboner3   )r   r[   r\   rh   rH   r   r   rj      s   
zBackboneMixin.__init__c                    s   t    t|  dS )a  
        Override `post_init` to always install capturing hooks, as backbone will ALWAYS capture outputs. We need to do
        it in `post_init`, as modules need to be already instantiated.
        It avoids some mixups with `torch.compile`, as the first hook installation will need/create a graph break,
        which can clash with external user call such as `model = torch.compile(model...)`.
        N)rD   	post_initr   r   rH   r   r   rm      s   
	zBackboneMixin.post_initc                 C   s   t | jdd}t | jdd}dd |jjD | _dd |jjD | _t|jj}|j }|dur=||kr=t	d| d|durN|| jkrNt	d	| d
| j| j_| j
|| dS )zj
        Initialize the backbone model from timm. The backbone must already be loaded to backbone
        r   Nr   c                 S      g | ]}|d  qS )moduler   r   stager   r   r   r          z5BackboneMixin._init_timm_backbone.<locals>.<listcomp>c                 S   rn   )num_chsr   rp   r   r   r   r      rr   z!Config has `out_features` set to z which doesn't match `out_features` from backbone's feature_info. Please check if your checkpoint has correct out features/indices saved.z Config has `stage_names` set to z which doesn't match `stage_names` from backbone's feature_info. Please check if your checkpoint has correct `stage_names` saved.)rX   rY   feature_infoinfor   num_featuresr#   r   module_namer3   r'   )r   ri   out_features_from_configstage_names_from_configr   r   r   r   r   rk      s    



z!BackboneMixin._init_timm_backbonec                 C   s   | j j| _| j   d | _d S r(   )rY   r   r%   rv   r   r   r   r   rl      s   


z)BackboneMixin._init_transformers_backbonec                 C      | j jS r(   )rY   r    r   r   r   r   r        zBackboneMixin.out_featuresr   c                 C      || j _dS )r?   N)rY   r   rA   r   r   r   r        c                 C   rz   r(   )rY   r$   r   r   r   r   r     r{   zBackboneMixin.out_indicesr   c                 C   r|   )rB   N)rY   r   rC   r   r   r   r     r}   c                    s    fddt  jD S )Nc                    s   i | ]
\}}| j | qS r   )rv   )r   irq   r   r   r   rU     s    z6BackboneMixin.out_feature_channels.<locals>.<dictcomp>)	enumerater   r   r   r   r   out_feature_channels  s   z"BackboneMixin.out_feature_channelsc                    s    fdd j D S )Nc                    r   r   )r   )r   namer   r   r   r      r   z*BackboneMixin.channels.<locals>.<listcomp>)r   r   r   r   r   channels  s   zBackboneMixin.channelsc                    sT   | j s	|dd  | jtjkr#tt| jj	  fdd|
 D }| |i |S )Noutput_attentionsc                    s   i | ]\}}| v r||qS r   r   rR   	signaturer   r   rU   '  rV   z>BackboneMixin.forward_with_filtered_kwargs.<locals>.<dictcomp>)rf   rF   re   r   r   dictinspectr   forward
parametersrZ   )r   r[   r\   r   r   r   forward_with_filtered_kwargs"  s   z*BackboneMixin.forward_with_filtered_kwargsrP   r   return_dictc                 C   s   t d)Nz7This method should be implemented by the derived class.)NotImplementedError)r   pixel_valuesrP   r   r   r   r   r   r   *  s   zBackboneMixin.forward)rg   N)NNN)r	   r
   r   re   r   __annotations__rf   boolrj   rm   rk   rl   rK   r   rL   r#   rM   r   r"   rN   r   r   r   r   rO   r   r   rH   r   rd      s<   
 

!



rd   default_backbonedefault_config_typedefault_config_kwargstimm_default_kwargsc                 K   sx  ddl m} ddlm} |dd}|di }	|dd ur$|dn|}
|dd  |d urK|rK|
d urK| d u rK|	sK|d	 dd|
i|} | |fS |
d ur| d u rt|
rt||
\}}||d
  }||	 |di |} | |fS |d	 dd|
i|	} | |fS | d u r|d urt	
d| d |pi }|| di |} | |fS t| tr| d
}|| }|| } | |fS )Nr   )PreTrainedConfig)CONFIG_MAPPINGuse_timm_backboneTbackbone_kwargsri   use_pretrained_backbonerh   
model_typezG`backbone_config` is `None`. Initializing the config with the default `z` vision config.r   )configuration_utilsr   models.autor   rF   rW   r   get_config_dictupdateloggerru   r!   r   	from_dict)backbone_configr   r   r   r   r\   r   r   r   r   ri   config_dictr/   config_classbackbone_model_typer   r   r   %consolidate_backbone_kwargs_to_config4  sH   





r   c                 C   s@   ddl m} t| dd}|du r|j| d}|S |j|d}|S )a>  
    Loads the backbone model from a config object.

    If the config is from the backbone model itself, then we return a backbone model with randomly initialized
    weights.

    If the config is from the parent model of the backbone model itself, then we load the pretrained backbone weights
    if specified.
    r   )AutoBackboner   N)rY   )r   r   rX   from_config)rY   r   r   ri   r   r   r   load_backbonef  s   
r   )NNNN)rJ   enumra   r   huggingface_hubr   utilsr   utils.output_capturingr   
get_loggerr	   r   Enumr   r   rc   rd   rM   r   r   r   r   r   r   r   <module>   s6   
} 
2