a
    h0E                     @   sH  d Z ddlZddlZddlmZ ddlmZmZmZ erDddl	m
Z
 G dd dejZeee  eee  eee  d	d
dZeee  eeee ee f  ee d	ddZeee  eeee ee f  ee eee ee f dddZG dd dZG dd dZdd Zeeee eeedf  ee dddZdS )zACollection of utils to be used by backbones and their components.    N)Iterable)TYPE_CHECKINGOptionalUnion   )PretrainedConfigc                   @   s   e Zd ZdZdZdS )BackboneTypeZtimmtransformersN)__name__
__module____qualname__TIMMTRANSFORMERS r   r   ]/var/www/html/assistant/venv/lib/python3.9/site-packages/transformers/utils/backbone_utils.pyr      s   r   out_featuresout_indicesstage_namesc                    s  du rt d durt tfs6t dt  tfdd D r`t d d  t tt krt d    fd	d
D  }krt d| d  |durt|tst dt| tfdd|D }tfdd|D rt d d| t|tt|kr^d| }|||krPd| dnd7 }t ||tt|krdd
 tt	||dd dD }t d| d|  dur|durt t|krt d fdd
|D krt ddS )zW
    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   | ]}| vV  qd S Nr   .0Zfeatr   r   r   	<genexpr>,       z2verify_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 | ]}| v r|qS r   r   r   r   r   r   
<listcomp>0   r   z3verify_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   n|V  qdS )r   Nlenr   idxr   r   r   r   9   r   c                 3   s"   | ]}|t t vr|V  qd S r   )ranger   r   r   r   r   r   :   r   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   A   r   c                 S   s   | d S )Nr   r   )xr   r   r   <lambda>A   r   z1verify_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                    s   g | ]} | qS r   r   r   r   r   r   r   I   r   zQout_features and out_indices should correspond to the same stages if both are set)

ValueError
isinstancelisttypeanyr   settuplesortedzip)r   r   r   Zsorted_featsZpositive_indicesmsgZsorted_negativer   )r   r   r   verify_out_features_out_indices    sB    


 r1   c                    sx   |du r*| du r*t  d g} d g} nF|du rN| durN fdd| D }n"| du rp|durp fdd|D } | |fS )a  
    Finds the corresponding `out_features` and `out_indices` for the given `stage_names`.

    The logic is as follows:
        - `out_features` not set, `out_indices` set: `out_features` is set to the `out_features` corresponding to the
        `out_indices`.
        - `out_indices` not set, `out_features` set: `out_indices` is set to the `out_indices` corresponding to the
        `out_features`.
        - `out_indices` and `out_features` not set: `out_indices` and `out_features` are set to the last stage.
        - `out_indices` and `out_features` set: input `out_indices` and `out_features` are returned.

    Args:
        out_features (`list[str]`): The names of the features for the backbone to output.
        out_indices (`list[int]` or `tuple[int]`): The indices of the features for the backbone to output.
        stage_names (`list[str]`): The names of the stages of the backbone.
    N   c                    s   g | ]}  |qS r   )index)r   layerr   r   r   r   f   r   z9_align_output_features_output_indices.<locals>.<listcomp>c                    s   g | ]} | qS r   r   r   r   r   r   r   h   r   r   r   r   r   r   %_align_output_features_output_indicesM   s    r6   )r   r   r   returnc                 C   sJ   |durt |nd}t| ||d t| ||d\}}t|||d ||fS )a`  
    Get the `out_features` and `out_indices` so that they are aligned.

    The logic is as follows:
        - `out_features` not set, `out_indices` set: `out_features` is set to the `out_features` corresponding to the
        `out_indices`.
        - `out_indices` not set, `out_features` set: `out_indices` is set to the `out_indices` corresponding to the
        `out_features`.
        - `out_indices` and `out_features` not set: `out_indices` and `out_features` are set to the last stage.
        - `out_indices` and `out_features` set: they are verified to be aligned.

    Args:
        out_features (`list[str]`): The names of the features for the backbone to output.
        out_indices (`list[int]` or `tuple[int]`): The indices of the features for the backbone to output.
        stage_names (`list[str]`): The names of the stages of the backbone.
    Nr   )r)   r1   r6   )r   r   r   Zoutput_featuresZoutput_indicesr   r   r   *get_aligned_output_features_output_indicesl   s    
r8   c                       s   e Zd ZU dZee ed< dZeed< ddddZ	dddd	Z
ddd
dZedd Zejee dddZedd Zejeee ee f dddZedd Zedd Zdd Zdee ee ee dddZ fddZ  ZS ) BackboneMixinNbackbone_typeThas_attentions)r7   c                 C   s   t | dddu rtddd | jjjD | _dd | jjjD | _t| jjj}| jj	 }t
||| jd || | _| _dS )zo
        Initialize the backbone model from timm The backbone must already be loaded to self._backbone
        	_backboneNz=self._backbone must be set before calling _init_timm_backbonec                 S   s   g | ]}|d  qS )moduler   r   stager   r   r   r      r   z5BackboneMixin._init_timm_backbone.<locals>.<listcomp>c                 S   s   g | ]}|d  qS )Znum_chsr   r>   r   r   r   r      r   r   )getattrr'   r<   Zfeature_infoinfor   num_featuresr)   r   module_namer1   _out_features_out_indices)selfconfigr   r   r   r   r   _init_timm_backbone   s    z!BackboneMixin._init_timm_backbonec                 C   sH   t |d}t |dd }t |dd }|| _t|||d\| _| _d | _d S )Nr   r   r   r   )r@   r   r8   rD   rE   rB   )rF   rG   r   r   r   r   r   r   _init_transformers_backbone   s    
z)BackboneMixin._init_transformers_backbonec                 C   sn   || _ t|dd| _| jr tjntj| _| jtjkr@| | n*| jtjkrX| | nt	d| j ddS )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.
        use_timm_backboneFzbackbone_type z not supported.N)
rG   r@   rJ   r   r   r   r:   rH   rI   r'   )rF   rG   r   r   r   _init_backbone   s    zBackboneMixin._init_backbonec                 C   s   | j S r   rD   rF   r   r   r   r      s    zBackboneMixin.out_featuresr   c                 C   s   t |d| jd\| _| _dS z
        Set the out_features attribute. This will also update the out_indices attribute to match the new out_features.
        Nr   r8   r   rD   rE   rF   r   r   r   r   r      s    c                 C   s   | j S r   rE   rM   r   r   r   r      s    zBackboneMixin.out_indicesr   c                 C   s   t d|| jd\| _| _dS z
        Set the out_indices attribute. This will also update the out_features attribute to match the new out_indices.
        Nr   rO   rF   r   r   r   r   r      s    c                    s    fddt  jD S )Nc                    s   i | ]\}}| j | qS r   )rB   )r   ir?   rM   r   r   
<dictcomp>   r   z6BackboneMixin.out_feature_channels.<locals>.<dictcomp>)	enumerater   rM   r   rM   r   out_feature_channels   s    z"BackboneMixin.out_feature_channelsc                    s    fdd j D S )Nc                    s   g | ]} j | qS r   )rX   )r   namerM   r   r   r      r   z*BackboneMixin.channels.<locals>.<listcomp>r   rM   r   rM   r   channels   s    zBackboneMixin.channelsc                    sT   | j s|dd  | jtjkrFtt| jj	  fdd|
 D }| |i |S )Noutput_attentionsc                    s   i | ]\}}| v r||qS r   r   )r   kv	signaturer   r   rV      r   z>BackboneMixin.forward_with_filtered_kwargs.<locals>.<dictcomp>)r;   popr:   r   r   dictinspectr_   forward
parametersitems)rF   argskwargsr   r^   r   forward_with_filtered_kwargs   s    z*BackboneMixin.forward_with_filtered_kwargs)output_hidden_statesr[   return_dictc                 C   s   t dd S )Nz7This method should be implemented by the derived class.)NotImplementedError)rF   Zpixel_valuesri   r[   rj   r   r   r   rc      s    zBackboneMixin.forwardc                    s*   t   }|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.
        rD   r   rE   r   superto_dictr`   rF   output	__class__r   r   ro      s    
zBackboneMixin.to_dict)NNN)r
   r   r   r:   r   r   __annotations__r;   boolrH   rI   rK   propertyr   setterr)   strr   r   r-   intrX   rZ   rh   rc   ro   __classcell__r   r   rr   r   r9      s6   


 

   	r9   c                       st   e Zd ZdZedd Zejee dddZedd Z	e	je
ee ee f d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.
    c                 C   s   | j S r   rL   rM   r   r   r   r     s    z BackboneConfigMixin.out_featuresr   c                 C   s   t |d| jd\| _| _dS rN   rO   rP   r   r   r   r     s    c                 C   s   | j S r   rQ   rM   r   r   r   r     s    zBackboneConfigMixin.out_indicesrR   c                 C   s   t d|| jd\| _| _dS rS   rO   rT   r   r   r   r     s    c                    s*   t   }|d|d< |d|d< |S rl   rm   rp   rr   r   r   ro   '  s    
zBackboneConfigMixin.to_dict)r
   r   r   __doc__rv   r   rw   r)   rx   r   r   r-   ry   ro   rz   r   r   rr   r   r{     s   

 r{   c           	      C   s^  ddl m}m} t| dd}t| dd}t| dd}t| dd}t| dd}|du rXi n|}|rp|durptd	|dur|dur|durtd
|du r|du r|du r|jf d| i|S |r|du rtd|j|f||d|}np|r|du rtd|j|fi |}nD|du r2|du r2td|du rN|j|fi |}|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   )AutoBackbone
AutoConfigbackbone_configNrJ   use_pretrained_backbonebackbonebackbone_kwargs?You can't specify both `backbone_kwargs` and `backbone_config`.z>Cannot specify both config.backbone_config and config.backbonerG   z8config.backbone must be set if use_timm_backbone is True)rJ   r   z>config.backbone must be set if use_pretrained_backbone is Truez<Either config.backbone_config or config.backbone must be set)rG   )r	   r}   r~   r@   r'   from_configZfrom_pretrained)	rG   r}   r~   r   rJ   r   Zbackbone_checkpointr   r   r   r   r   load_backbone2  sD    


r   r   rJ   r   r   r   r   c                 C   sL   |dur|durt d|dur,| r,t d|durH|rH|durHt ddS )zR
    Verify that the config arguments to be passed to load_backbone are valid
    Nz8You can't specify both `backbone` and `backbone_config`.zAYou can't specify both `backbone_config` and `use_timm_backbone`.r   )r'   r   r   r   r    verify_backbone_config_argumentsj  s    
r   )r|   enumrb   collections.abcr   typingr   r   r   Zconfiguration_utilsr   Enumr   rx   ry   r1   r)   r-   r6   r8   r9   r{   r   ru   ra   r   r   r   r   r   <module>   s6   .
 
 |*9