
    ^j~;                         d Z ddlZddlmZmZmZ ddlZddlmZ ddl	mc m
Z ddlmZ ddlmZ ddlmZ  ej$                  e      Z G d d	ej*                        Z G d
 de      Zy)zJToken-based distillation training task for models with distillation heads.    N)DictOptionalUnion)create_model)unwrap_model   )TrainingTaskc                   x    e Zd ZdZ	 	 	 	 	 ddeeej                  f   dee	   de	dee   dee
j                     dee
j                     f fdZ	 	 dd	ed
ee   dd fdZde
j                  de
j                  fdZ	 	 dde
j                  dee
j                     dee
j                     de
j                  fdZ xZS )TokenDistillationTeacheraK  Wrapper for a teacher model used in token-based distillation.

    Creates and manages a pre-trained teacher model for token distillation,
    handling model creation and normalization differences between teacher and student.

    Can be created from:
    - A model name string (creates the model internally)
    - An existing nn.Module (wraps it with the necessary interface)

    Args:
        model_name_or_module: Either a model name string or an nn.Module
        num_classes: Number of output classes (required if model_name_or_module is a string)
        in_chans: Number of input channels (used if model_name_or_module is a string)
        pretrained_path: Optional path to pretrained weights (used if model_name_or_module is a string)
        device: Device to place the model on
        dtype: Model dtype (uses float32 if None)
    model_name_or_modulenum_classesin_chanspretrained_pathdevicedtypec           	         t         |           t        |t              rAt        j                  d| d       ddi}|rt        ||      |d<   t        d|||||d|}n>t        |t        j                        r|}n!t        dt        |      j                         |j                          || _        t        |      }	t!        |	d	      r9|	j"                  j%                  d
d      }
|	j"                  j%                  dd      }nd}
d}t'        j(                  |
||      j+                  dddd      }t'        j(                  |||      j+                  dddd      }| j-                  d|d       | j-                  d|d       y )Nz,Creating token distillation teacher model: ''
pretrainedT)filer   pretrained_cfg_overlay)
model_namer   r   r   r   z8model_name_or_module must be a string or nn.Module, got pretrained_cfgmean)g
ףp=
?gv/?gCl?std)gZd;O?gy&1?g?r   r   r   mean_kdF
persistentstd_kd )super__init__
isinstancestr_loggerinfodictr   nnModule	TypeErrortype__name__evalmodelr   hasattrr   gettorchtensorviewregister_buffer)selfr   r   r   r   r   r   pretrained_kwargsr/   model_unwrappedr   r   r   r    	__class__s                 g/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/timm/task/token_distillation.pyr#   z!TokenDistillationTeacher.__init__$   s    	*C0LLGH\G]]^_`!-t 4>B( +?!":;
 ! /'! $E ,bii8(EJ4PdKeKnKnJop  	


 'u-?$45"1155f>STD!0044U<QRC(D'C,,tF%@EEaQPQRc&>CCAr1aPYEBXv%@    backendmodereturnc                 V    t        j                  | j                  f||d|| _        | S )z Compile teacher logit inference.r<   r=   )r2   compiler/   r6   r<   r=   compile_kwargss       r:   rA   z TokenDistillationTeacher.compileY   s)     ]]4::\wT\^\
r;   inputc                 $    | j                  |      S )zForward pass through teacher model.

        Args:
            input: Input tensor (should already be normalized for teacher)

        Returns:
            Teacher logits
        )r/   )r6   rD   s     r:   forwardz TokenDistillationTeacher.forwardc   s     zz%  r;   student_meanstudent_stdc                     |||S t        j                  || j                        r"t        j                  || j                        r|S ||z  |z   | j                  z
  | j                  z  S )ao  Normalize input to match teacher's expected normalization.

        Args:
            input: Input tensor (already normalized for student)
            student_mean: Student normalization mean buffer [1, 3, 1, 1]
            student_std: Student normalization std buffer [1, 3, 1, 1]

        Returns:
            Input tensor normalized for the teacher model
        )r2   equalr   r    )r6   rD   rG   rH   s       r:   normalize_inputz(TokenDistillationTeacher.normalize_inputn   sa      ;#6L;;|T\\2u{{;PTP[P[7\L#l2T\\AT[[PPr;   )N   NNNinductorN)NN)r-   
__module____qualname____doc__r   r%   r)   r*   r   intr2   r   r   r#   rA   TensorrF   rK   __classcell__r9   s   @r:   r   r      s!   * *.-1-1+/3A"'RYY"73A "#3A 	3A
 &c]3A U\\*3A EKK(3An &"& 3-
 
$	!U\\ 	!ell 	! 4826	Q<<Q #5<<0Q "%,,/	Q
 
Qr;   r   c                       e Zd ZdZ	 	 	 	 	 	 	 	 	 ddej
                  deeej
                  ef   de	ej
                     de	e   dede	e
   de	e
   d	e
d
e	ej                     de	ej                     def fdZ	 dde	e   dd fdZ	 	 ddede	e   dej
                  fdZdej&                  dej&                  deeej&                  f   fdZ xZS )TokenDistillationTaska  Token-based distillation task for models with distillation heads.

    For models like DeiT that have a dedicated distillation token/head that returns
    a tuple (main_logits, dist_logits) when distilled_training is enabled. The main
    head is trained against ground truth labels while the distillation head matches
    teacher outputs.

    Supports two distillation modes:
    - 'soft': KL divergence with temperature scaling (default)
    - 'hard': Cross-entropy with teacher's hard predictions (argmax)

    Loss weighting supports two modes:
    1. Independent weights: loss = task_loss_weight * task_loss + distill_loss_weight * distill_loss
    2. Complementary mode: loss = task_loss_weight * task_loss + (1 - task_loss_weight) * distill_loss
       (used when only task_loss_weight is specified)

    Args:
        student_model: Student model with set_distilled_training() method
        teacher_model: Teacher model - can be a model name string, nn.Module, or TokenDistillationTeacher
        criterion: Task loss function for main head (default: CrossEntropyLoss)
        teacher_pretrained_path: Path to teacher pretrained weights (used when teacher_model is a string)
        distill_type: 'soft' for KL-div or 'hard' for CE with teacher argmax
        distill_loss_weight: Weight for distillation loss
        task_loss_weight: Weight for task loss
        temperature: Softmax temperature for soft distillation (ignored for hard)
        device: Device for task tensors/buffers
        dtype: Dtype for task tensors/buffers
        verbose: Enable info logging

    Example:
        >>> # With model name string (num_classes/in_chans inferred from student)
        >>> task = TokenDistillationTask(
        ...     student_model=model, teacher_model='deit_base_patch16_224',
        ...     criterion=nn.CrossEntropyLoss(),
        ...     distill_type='soft', temperature=3.0, task_loss_weight=0.5,
        ...     device=torch.device('cuda'),
        ... )
        >>> # With raw model
        >>> task = TokenDistillationTask(
        ...     student_model=model, teacher_model=my_teacher_model,
        ...     criterion=nn.CrossEntropyLoss(),
        ...     distill_type='hard', task_loss_weight=0.5,
        ... )
    student_modelteacher_model	criterionteacher_pretrained_pathdistill_typedistill_loss_weighttask_loss_weighttemperaturer   r   verbosec                    t         |   |	|
|       t        |      }t        |d      s#t	        d|j
                  j                   d      |j                  d       t        |t              r|}nt        |t              st        |t        j                        r>|j                  }|j                  }t        ||||| j                  | j                         }n!t#        dt%        |      j                         || _        || _        ||nt        j*                         | _        || _        || _        |dvrt	        d	| d
      t3        j4                  |j6                  d   | j                  | j                         j9                  dddd      }t3        j4                  |j6                  d   | j                  | j                         j9                  dddd      }| j;                  d|d       | j;                  d|d       |D|| _        ||nd| _        | j@                  rtB        jE                  d| j>                   d|        n|C|| _        d|z
  | _        | j@                  rotB        jE                  d| d| j<                          nId| _        d| _        | j@                  r/tB        jE                  d| j>                   d| j<                          | j@                  rtB        jE                  d| d|        y y )N)r   r   r`   set_distilled_trainingzModel z does not have 'set_distilled_training' method. TokenDistillationTask requires a model with a distillation head (e.g., DeiT distilled variants).T)r   r   r   r   r   r   zWteacher_model must be a model name string, nn.Module, or TokenDistillationTeacher, got )softhardzUnsupported distill_type 'z'. Must be 'soft' or 'hard'.r   r   r   r   r   rG   Fr   rH         ?z9TokenDistillationTask: Independent weights - task_weight=z, distill_weight=z8TokenDistillationTask: Complementary mode - task_weight=z;TokenDistillationTask: Default equal weights - task_weight=z$TokenDistillationTask: distill_type=z, temperature=)#r"   r#   r   r0   
ValueErrorr9   r-   rb   r$   r   r%   r)   r*   r   r   r   r   r+   r,   trainable_moduleteacherCrossEntropyLossrZ   r\   r_   r2   r3   r   r4   r5   r]   r^   r`   r&   r'   )r6   rX   rY   rZ   r[   r\   r]   r^   r_   r   r   r`   student_unwrappedrh   r   r   rG   rH   r9   s                     r:   r#   zTokenDistillationTask.__init__   s    	eWE )7(*BC*44==> ?s s  	006 m%=>#Gs+z-/S+77K(11H.%2'! 7{{jjG M*3346 
 !.&/&;ATATAV(&//9,Gcdee ||,,V4;;**
 $q"a
	 	
 ll,,U3;;**
 $q"a
	 	
 	^\eL]KEJ *':D$8H8T$4Z]D!||##'#8#8"99JK^J_a )$4D!'*-='=D$||##3"44EdF^F^E_a (+D$$'D!||##'#8#8"99J4KcKcJdf
 <<LL6|nNS^R_` r;   
device_idsr>   c                     ddl m} | j                  j                         D ]	  }d|_          || j
                  fd|i|| _        | S )a  Prepare task for distributed training.

        Wraps the student model in DistributedDataParallel (DDP) while leaving
        the frozen teacher model unwrapped.

        Args:
            device_ids: List of device IDs for DDP (e.g., [local_rank])
            **ddp_kwargs: Additional arguments passed to DistributedDataParallel

        Returns:
            self (for method chaining)
        r   )DistributedDataParallelFrk   )torch.nn.parallelrm   rh   
parametersrequires_gradrg   )r6   rk   
ddp_kwargsDDPparams        r:   prepare_distributedz)TokenDistillationTask.prepare_distributed  sQ    " 	E\\,,. 	(E"'E	( !$D$9$9 _j _T^ _r;   r<   r=   c                     t        j                  | j                  f||d|| _        | j                  | _         | j                  j                  d||d| | j                  S )z=Compile student eval/train forward and teacher logit forward.r@   r!   )r2   rA   rg   
eval_modelrh   rB   s       r:   rA   zTokenDistillationTask.compile5  s`     !&d.C.C rW[_ rcq r//JW4J>J$$$r;   rD   targetc                    | j                  |      }|\  }}| j                  ||      }t        j                         5  | j                  j                  || j                  | j                        }| j	                  |j                               }ddd       | j                  dk(  rrt        j                  || j                  z  d      }	t        j                  | j                  z  d      }
t        j                  |	|
dd      | j                  dz  z  }n(j                  d      }t        j                  ||      }| j                   |z  | j"                  |z  z   }||||d	S # 1 sw Y   xY w)
a  Forward pass with token distillation.

        Args:
            input: Input tensor [B, C, H, W]
            target: Target labels [B]

        Returns:
            Dictionary containing:
                - 'loss': Combined training loss (task + distillation)
                - 'output': Main head logits (for metrics)
                - 'task_loss': Classification loss component
                - 'distill_loss': Distillation loss component
        Nrc   r   )dim	batchmeanT)	reduction
log_target   )lossoutput	task_lossdistill_loss)rg   rZ   r2   no_gradrh   rK   rG   rH   detachr\   Flog_softmaxr_   kl_divargmaxcross_entropyr^   r]   )r6   rD   rw   student_outputmain_logitsdist_logitsr   input_kdteacher_logitsprob_sprob_tr   teacher_hard
total_losss                 r:   rF   zTokenDistillationTask.forwardB  sR   & ..u5#1 [ NN;7	 ]]_ 	=||33E4;L;LdN^N^_H!\\(//*;<N	=
 &]];1A1A#ArJF]]>D4D4D#D"MF88FFkVZ[_c_o_ost_tuL)00R08L??;EL**Y69Q9QT`9``
 !"(	
 	
	= 	=s   AE%%E.)	NNrc   NNre   NNT)NrM   )r-   rO   rP   rQ   r)   r*   r   r%   r   r   floatr2   r   r   boolr#   listrt   rA   rS   r   rF   rT   rU   s   @r:   rW   rW      sh   +b .259 &3704!$-1+/ g99g !bii1I!IJg  		*	g
 &.c]g g "*%g 'uog g U\\*g EKK(g gV *.  
!	6 &"&%% 3-%
 
%.
<<.
 LL.
 
c5<<	 	.
r;   rW   )rQ   loggingtypingr   r   r   r2   torch.nnr)   torch.nn.functional
functionalr   timm.modelsr   
timm.utilsr   taskr	   	getLoggerr-   r&   r*   r   rW   r!   r;   r:   <module>r      s[    P  ( (     $ # 
'

H
%qQryy qQhk
L k
r;   