
    ^jƎ              
         U d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	m
Z
 ddlZddlmc mZ ddlmZmZ ddlmZ ddlmZmZ ddlmZ dd	lmZmZ dd
lmZmZm Z  ddl!m"Z" ddl#m$Z$  e$       Z%dddddddddd	Z&de'd<    G d de      Z(y)z4LightningModule for RF-DETR training and validation.    )annotationsN)AnyDictOptionalTuple)LightningModuleseed_everything)_namespace_from_configs)ModelConfigTrainConfig)compute_multi_scale_scales)build_criterion_from_configbuild_model_from_config)
apply_lorainterpolate_position_embeddingsload_pretrain_weights)get_param_dict)
get_loggerloss_clsloss_box	loss_gioumask_ce	mask_dicekp_l1kp_findkp_viskp_nll)	loss_ce	loss_bboxr   loss_mask_celoss_mask_diceloss_keypoints_l1loss_keypoints_findableloss_keypoints_visibleloss_keypoints_nllzdict[str, str]_TRAIN_PROGRESS_LOSS_ALIASESc                  2    e Zd ZdZd fdZddZddZddZddZ	 	 	 	 	 	 ddZ		 	 	 	 	 	 ddZ
dd	Zdd
Zd dZddZed!d       Z	 	 	 	 	 	 	 	 d"dZ	 	 	 	 	 	 	 	 d"dZd#dZed$d       Zd%dZ	 	 d&	 	 	 	 	 	 	 d' fdZd#dZd(d)dZd*dZd+dZ xZS ),RFDETRModelModulezLightningModule wrapping the RF-DETR model and training loop.

    Args:
        model_config: Architecture configuration.
        train_config: Training hyperparameter configuration.
    c                ,   t         |           || _        || _        t	        t        |dd            | _        | j                   | _        d | _        d| _	        t        ||      | _        |j                  jt        | j                  | j                         |j                  r>t        | j                  dd       }t        |      r |        t         j#                  d       |j$                  rt'        | j                         t)        | j                  | j                        \  | _        | _        ddlm} t3        |j4                        j7                         }|dv }|j8                  xr |dk(  xr |xr |j:                   }|j8                  r!|j:                  rt         j#                  d	       |red
t<        j>                  j@                  _!        d
t<        j>                  j@                  _"        t=        j8                  | j                  d
      | _        y y )Nuse_grouppose_keypointsF"reset_keypoint_gaussian_parameterszVReset keypoint Gaussian precision outputs to unit values after pretrained weight load.r   )DEVICE>   gpuautocudar/   zQDisabling torch.compile because multi_scale=True introduces dynamic input shapes.T)dynamic)#super__init__model_configtrain_configboolgetattr_use_manual_optimizationautomatic_optimization_accumulated_box_normalizerstrict_loadingr   modelpretrain_weightsr   r*   callableloggerinfobackbone_lorar   r   	criterionpostprocessrfdetr.configr,   stracceleratorlowercompilemulti_scaletorch_dynamoconfigsuppress_errorscapture_scalar_outputs)	selfr3   r4   r+   r,   rE   uses_cuda_acceleratorcompile_enabled	__class__s	           g/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/training/module_model.pyr2   zRFDETRModelModule.__init__2   s   (( /37<Ibdi3j.k%*.*G*G&G#@D( $ -\<H
((4 "$**d.?.?@335<TZZImos5t2>?68KKp %%tzz" ,GtGXGXZ^ZkZk+l(( 	),22399; +/F F  pVv%5p:OpXdXpXpTp 	 L$<$<KKkl 48EMM  0:>EMM  7tzz4@DJ     c                    | j                   j                  /t        | j                   j                  | j                  z   d       yy)zSeed RNGs at fit start when ``TrainConfig.seed`` is set.

        This avoids hidden global side-effects in ``build_trainer`` while still preserving deterministic training
        behaviour for actual fit runs.
        NT)workers)r4   seedr	   global_rankrN   s    rR   on_fit_startzRFDETRModelModule.on_fit_startw   s<     !!-D--22T5E5EEtT .rS   c                   | j                   }| j                  }|j                  r0|j                  s"|\  }}t	        |j
                  |j                  |j                  |j                        }| j                  j                  }t        j                  |       t        j                  |      }	t        j                         5  t!        j"                  |j$                  |	dd      |_        t!        j"                  |j&                  j)                  d      j+                         |	d      j-                  d      j/                         |_        ddd       yyy# 1 sw Y   yxY w)an  Apply optional multi-scale resize to the incoming batch.

        Modifications to ``batch`` (in-place on ``NestedTensor``) are visible in ``training_step`` because they share
        the same object.

        Args:
            batch: Tuple of (NestedTensor samples, list of target dicts).
            batch_idx: Index of the current batch within the epoch.
        bilinearF)sizemodealign_corners   nearest)r\   r]   N)r4   r3   rH   do_random_resize_via_paddingr   
resolutionexpanded_scales
patch_sizenum_windowstrainerglobal_steprandomrV   choicerI   no_gradFinterpolatetensorsmask	unsqueezefloatsqueezer5   )
rN   batch	batch_idxtcmcsamples_scalesstepscales
             rR   on_train_batch_startz&RFDETRModelModule.on_train_batch_start   s    >>""A"AJGQ/r?Q?QSUS`S`bdbpbpqF<<++DKKMM&)E "#--eR\lq"rMM',,"8"8";"A"A"C%V_`hhijkppr   #B> s   B
EE c                    | j                   D	 | j                         }t        |t              r|n|gD ]  }|j	                           	 d| _         yd| _         y# t
        $ r
 Y d| _         yw xY w)ay  Reset the accumulated box normalizer at the start of every training epoch.

        Lightning may reuse the module across epochs without calling ``_step_optimizer`` at the boundary (for example
        when an epoch ends mid-accumulation window with a non-divisible batch count). Clearing the accumulator here
        guarantees the manual-optimization path always starts each epoch from a known state, so the first microbatch's
        gradients are scaled by its own box count and not by a stale previous-epoch denominator.

        This is a no-op for non-keypoint models because they use Lightning's automatic optimization path and never
        populate ``self._accumulated_box_normalizer``.

        Note: on finite datasets the final-batch fallback in ``_should_step_optimizer`` always flushes a partial
        trailing window, so this reset is the only change needed.  On IterableDatasets (infinite
        ``num_training_batches``) a partial window may survive epoch end with un-stepped gradients; those are
        discarded here and the optimizer is zeroed so the first microbatch of the new epoch starts from a clean state.
        N)r9   
optimizers
isinstancelist	zero_gradRuntimeError)rN   optsopts      rR   on_train_epoch_startz&RFDETRModelModule.on_train_epoch_start   ss      ++7(#-dD#94v $CMMO$ ,0(4(   +/(s   :A 	A,+A,c           
     V   |\  }}t        |      }| j                  ||      }| j                  r)| j                  ||      \  }}| j	                  ||      }	n| j                  ||      d}	| j
                  j                  t        fdD              }
t        dt        | j                  j                              }| j                  r|
n|
|z  }t        | j                  j                        }t        | j                  j                        }| j!                  j#                         D ci c]  \  }}d| | c}}|d||       | j%                  d|
d|d||	       | j'                  |
|
       | j)                         }t+        |t,              r|d   }|j.                  D cg c]  }d|v s|d    }}|r]|d   }t1        |      }t        |      }| j%                  d|ddd       | j%                  d|ddd       | j%                  d|ddd       | j                  r3| j3                  |	       | j5                  |      r| j7                  |       | j                  j8                  rt;        j<                         5  t;        j>                  |D cg c]  }|d   	 c}      }| j@                  jB                  }|j#                         D ci c]@  \  }}|dv r7t+        |t:        jD                        r||jF                  dk\  r|ddd|f   n|B }}}| jI                  ||      }ddd       | j                  r|jK                         n|| jM                        |dS | j                  r|jK                         S |S c c}}w c c}w c c}w c c}}w # 1 sw Y   nxY w)a  Compute loss for one training step and log metrics.

        PTL handles AMP (``precision``) without a manual ``GradScaler``. Keypoint models perform manual optimization so
        box-count loss normalization is based on the full accumulated effective batch rather than each microbatch
        independently; detection and segmentation models keep Lightning's automatic optimization path.

        Args:
            batch: Tuple of (NestedTensor samples, list of target dicts).
            batch_idx: Batch index within the epoch.

        Returns:
            Scalar loss tensor by default. When ``compute_train_metrics=True``,
            returns a Lightning-compatible dict containing ``loss`` plus
            detached postprocessed predictions for train mAP logging.
        Nc              3  >   K   | ]  }|v s|   |   z    y wN .0k	loss_dictweight_dicts     rR   	<genexpr>z2RFDETRModelModule.training_step.<locals>.<genexpr>   s%     XQqKGW9Q<+a.0X   	r_   ztrain/Ton_stepon_epoch	sync_dist
batch_sizez
train/lossF)prog_barr   r   r   r   r   r   lrztrain/lr)r   r   r   ztrain/lr_minztrain/lr_max	orig_size)pred_logits
pred_boxes
pred_maskspred_keypoints   )lossresultstargets)'lenr;   r7   _compute_train_losses_scale_loss_for_accumulationrA   r   summaxintrf   accumulate_grad_batchesr5   r4   train_log_sync_disttrain_log_on_steplog_dictitemslog_log_train_progress_metricsr}   r~   r   param_groupsminmanual_backward_should_step_optimizer_step_optimizercompute_train_metricsrI   rj   stackr3   num_queriesTensorndimrB   detach_detach_results)rN   rr   rs   rv   r   r   outputsraw_loss
normalizerloss_for_backwardr   r   loss_for_returnr   r   r   v	optimizerpg	group_lrsbase_lrmin_lrmax_lrt
orig_sizesnqinference_outputsr   r   r   s                               @@rR   training_stepzRFDETRModelModule.training_step   s     !\
**Wg.((.2.H.HRY.Z+Ix $ A A(J Ww8I $nn00X)XX #&aT\\-Q-Q)R"S"&"?"?$TLcEc"4#4#4#H#HI !2!2!D!DE)2):;AvaS\1_;%)! 	 	
 	%)! 	 	
 	((yZ(POO%	i&!!I )2(>(>M"$"*RXM	MlG^F^FHHZ5$QVHWHH^VeTTYHZHH^VeTTYHZ((  !23**95$$Y/22 J"[[')JQ!K.)JK
 &&22
 !(%1YY"1ell3 AFFaKqCRCyQ6%! % **+<jI!J$ 594Q4Q..0Wf//8" 
 ,0+H+H%%']o]s <, N *K%J Js=   1N	
-	N7NNN
(0NANNNN(c                  	 | j                   j                  	t        | j                   dd      s+t        t	        | j                         j
                   d      | j                   j                  ||      }| j                  ||t        j                  |            j                         D ci c]  \  }}||	v r||z  n| }}}t        	fdD              }|||fS c c}}w )aN  Compute normalized losses for logging and raw weighted loss for backward.

        Args:
            outputs: Model output dictionary.
            targets: Target dictionaries for the current batch.

        Returns:
            A tuple of normalized loss dictionary, unnormalized weighted loss numerator, and box normalizer.
        !supports_loss_normalizer_overrideFa  .supports_loss_normalizer_override is False; manual optimization (keypoint models) requires a criterion that accepts a num_boxes keyword argument. Set supports_loss_normalizer_override = True on your criterion subclass and implement the num_boxes parameter in forward().)	num_boxesc              3  >   K   | ]  }|v s|   |   z    y wr   r   )r   r   numerator_loss_dictr   s     rR   r   z:RFDETRModelModule._compute_train_losses.<locals>.<genexpr>4  s)     p1_`do_o*1-A>pr   )rA   r   r6   
ValueErrortype__name__num_boxes_for_targetsrI   	ones_liker   r   )
rN   r   r   r   keyvaluer   r   r   r   s
           @@rR   r   z'RFDETRModelModule._compute_train_losses  s     nn00t~~'JER'001 2^ ^  ^^99'7K
"nnWgYcIdne XkWpWpWr
ISeCsk'9#uD
	 
 pH[pp(J..	
s   1C$c                    |j                         }| j                  }||n||z   }|| j                  ||z         |j                         | _        ||z  S )a$  Scale the current numerator loss by the accumulated box denominator.

        Args:
            raw_loss: Current microbatch weighted loss numerator.
            normalizer: Current microbatch box denominator.

        Returns:
            Loss scalar to pass to ``manual_backward``.
        )r   r9   _rescale_accumulated_gradients)rN   r   r   previous_normalizeraccumulated_normalizers        rR   r   z.RFDETRModelModule._scale_loss_for_accumulation7  sj      &&(
">>/B/JPcfpPp*//0CF\0\]+A+H+H+J(000rS   c                    | j                         D ]c  }|j                  |j                  j                  |j                  |j                  j                  |j                  j
                               e y)zRescale gradients already accumulated in the current optimizer window.

        Args:
            scale: Multiplicative factor that converts previous gradients from the old denominator to the new one.
        N)devicedtype)
parametersgradmul_tor   r   )rN   rz   	parameters      rR   r   z0RFDETRModelModule._rescale_accumulated_gradientsM  s\     * 	hI~~)##EHHINN4I4IQZQ_Q_QeQeH$fg	hrS   c                   t        dt        | j                  j                              }|dz   |z  dk(  ryt	        | j
                  dd      }t        |t        t        f      xr t        j                  |      xr |dz   |k\  S )u  Return whether the current batch closes an optimizer accumulation window.

        The optimizer steps when either:

        - The current batch closes a complete ``grad_accum_steps`` window
          (``(batch_idx + 1) % grad_accum_steps == 0``), or
        - This is the final batch of the epoch and a partial accumulation window
          is still open, so the trailing microbatches are not silently dropped.

        Lightning's ``Trainer.num_training_batches`` may be reported as ``float('inf')``
        for iterable / streaming datasets where the epoch length is unknown. In that case
        only the modulo path can ever close the window — the final-batch fallback is
        skipped because ``batch_idx + 1`` can never reach infinity.

        Args:
            batch_idx: Batch index within the epoch.

        Returns:
            ``True`` when the optimizer should step after this batch.
        r_   r   Tnum_training_batchesN)
r   r   r4   grad_accum_stepsr6   rf   r~   rp   mathisfinite)rN   rs   accum_stepsr   s       rR   r   z(RFDETRModelModule._should_step_optimizerW  s    * !S!2!2!C!CDEM[(A-&t||5KTR+c5\: 6236A!55	
rS   c                   t        | j                  dd      }|| j                  j                  }nt	        |t
        t        f      r|}nd}t        | j                  dd      }t	        |t              sd}||dkD  r| j                  |||       |j                          |j                          | j                          d| _        y)zClip gradients, step optimizer and scheduler, then reset accumulation state.

        Args:
            optimizer: Optimizer returned by Lightning.
        gradient_clip_valNgradient_clip_algorithmr   r   r   )r6   rf   r4   clip_max_normr~   r   rp   rD   clip_gradientsry   r   _step_lr_schedulerr9   )rN   r   trainer_gradient_clip_valr   r   s        rR   r   z!RFDETRModelModule._step_optimizerv  s     %,DLL:Mt$T!$, $ 1 1 ? ?1C<@ 9 $")$,,8QSW"X137&*#(->-B"3(?   
 	!+/(rS   c                    	 | j                         }|yt        |t              r|n|g}|D ]  }|j                           y# t        t        f$ r Y yw xY w)z9Step Lightning's scheduler object when one is configured.N)lr_schedulersAttributeErrorr   r~   r   ry   )rN   	scheduler
schedulersscheduler_items       rR   r   z$RFDETRModelModule._step_lr_scheduler  sf    	**,I ",Y"=YI;
( 	"N!	" - 		s   A AAc                    | D cg c]K  }|j                         D ci c]-  \  }}|t        j                  |      r|j                         n|/ c}}M c}}}S c c}}w c c}}}w )a  Detach postprocessed result tensors before handing them to callbacks.

        Args:
            results: Per-image postprocessed prediction dictionaries.

        Returns:
            Per-image dictionaries with tensor values detached from the graph.
        )r   rI   	is_tensorr   )r   resultr   r   s       rR   r   z!RFDETRModelModule._detach_results  s^     "
 
 Y_XdXdXfg*#uSEOOE$:%,,.Eg
 	
g
s   A"2AA"A"c          
         | j                  d|dddd|       t        j                         D ]1  \  }}|j                  |      }|| j                  ||dddd|       3 y)a!  Log compact per-step convergence metrics for the progress bar only.

        Args:
            loss: Unscaled aggregate training loss.
            loss_dict: Raw criterion loss dictionary.
            batch_size: Current batch size used by Lightning for metric reduction metadata.
        r   TF)r   r>   r   r   r   N)r   r&   r   get)rN   r   r   r   	loss_nameprogress_namer   s          rR   r   z-RFDETRModelModule._log_train_progress_metrics  s     	! 	 	
 )E(J(J(L 	$I}MM),E}HH%  		rS   c                   | j                  |j                         D ci c]  \  }}d| | c}}ddd|       | j                  d|ddd|       yc c}}w )a  Log aggregate and component validation losses.

        Args:
            loss: Aggregate weighted validation loss.
            loss_dict: Raw criterion loss dictionary.
            batch_size: Current batch size used by Lightning for metric reduction metadata.
        zval/FTr   zval/loss)r   r   r   r   N)r   r   r   )rN   r   r   r   r   r   s         rR   _log_val_loss_metricsz'RFDETRModelModule._log_val_loss_metrics  sd     	'0'89tq!tA3Z]9! 	 	
 	TD44\fg :s   A
c                  
 |\  }}| j                  |      }| j                  j                  rZ| j                  ||      
| j                  j                  t        
fd
D              }| j                  |
t        |             t        j                  |D cg c]  }|d   	 c}      }| j                  ||      }	|	|dS c c}w )a  Run forward pass and postprocess for one validation step.

        Returns raw results and targets so ``COCOEvalCallback`` can accumulate them across the epoch via
        ``on_validation_batch_end``.

        Args:
            batch: Tuple of (NestedTensor samples, list of target dicts).
            batch_idx: Batch index within the validation epoch.

        Returns:
            Dict with ``results`` (postprocessed predictions) and ``targets``.
        c              3  >   K   | ]  }|v s|   |   z    y wr   r   r   s     rR   r   z4RFDETRModelModule.validation_step.<locals>.<genexpr>  &     \1P[K[y|k!n4\r   r   r   r   r   )r;   r4   compute_val_lossrA   r   r   r   r   rI   r   rB   rN   rr   rs   rv   r   r   r   r   r   r   r   r   s             @@rR   validation_stepz!RFDETRModelModule.validation_step  s     !**W%--w8I..44K\i\\D&&tY3w<&P[['!BQ!K.!BC
""7J7"w77 "Cs   Cc                    | j                   j                  xra t        j                  j	                         xrA t        j                  j                         xr! t        | j                  j                        dv S )a  Return whether fused AdamW should be used for the current training configuration.

        Fused AdamW is only safe when the trainer's actual precision is a BF16 variant.  Checking GPU capability alone
        (``is_bf16_supported()``) is
        insufficient: on Ampere+ hardware that flag is always ``True`` even when
        the trainer is configured for ``32-true``, which causes a ``params, grads, exp_avgs, and exp_avg_sqs must have
        same dtype, device, and layout`` crash in DDP because gradient bucket views have non-matching strides in FP32.

        Returns:
            ``True`` when fused AdamW is both requested and safe to use.

        Examples:
            >>> from unittest.mock import patch
            >>> module = RFDETRModelModule.__new__(RFDETRModelModule)
            >>> module.model_config = type("Cfg", (), {"fused_optimizer": True})()
            >>> with patch("torch.cuda.is_available", return_value=False):
            ...     module._use_fused_optimizer
            False
        >   	bf16-true
bf16-mixedbf16)	r3   fused_optimizerrI   r/   is_availableis_bf16_supportedrD   rf   	precisionrX   s    rR   _use_fused_optimizerz&RFDETRModelModule._use_fused_optimizer  sd    , -- S

'')S

,,.S DLL**+/RR		
rS   c                (  
 | j                   t        | j                        }t        | j                  d| j                        }t        ||      }|D cg c]  }|d   j                  s| }}t        j                  j                  |j                  j                  | j                        }t        dt        j                              }t        | j                   j"                        }| j$                  r"t        dt'        j(                  ||z              n|t        dj*                  z        
t        
j,                  z        d

fd}t        j                  j.                  j1                  ||      }	||	ddd	S c c}w )ak  Build AdamW optimizer with layer-wise LR decay and LambdaLR scheduler.

        Uses ``trainer.estimated_stepping_batches`` for total step count so cosine annealing covers the full training
        run regardless of dataset size or accumulation settings.

        Returns:
            PTL optimizer config dict with optimizer and step-interval scheduler.
        	_orig_modparams)r   weight_decayfusedr_   c                v   | k  r!t        |       t        t        d            z  S j                  dk(  rpt        | z
        t        t        dz
              z  }j                  dj                  z
  dz  dt	        j
                  t        j                  |z        z   z  z   S | j                  z  k  ryy)Nr_   cosineg      ?g      ?g?)rp   r   lr_schedulerlr_min_factorr   cospilr_drop)current_stepprogresssteps_per_epochrt   total_stepswarmup_stepss     rR   	lr_lambdaz9RFDETRModelModule.configure_optimizers.<locals>.lr_lambdaK  s    l*\*U3q,3G-HHH(* !<=c![[gMgFh@ii''1r/?/?+?3*F!dhhW[W^W^aiWiNjJj*kkkbjj?::rS   )r!  ry   )r   interval)r   r  )r  r   returnrp   )r4   r
   r3   r6   r;   r   requires_gradrI   optimAdamWr   r  r  r   r   r   rf   estimated_stepping_batchesr7   r   ceilepochswarmup_epochsr  LambdaLR)rN   nsmodel_for_paramsparam_dictspr   r   microbatchesr!  r   r  rt   r  r   s             @@@@rR   configure_optimizersz&RFDETRModelModule.configure_optimizers  sj    $T%6%6;
 #4::{DJJG$R)9:"-KQ81J1JqKKKK%%uu++	 & 
	  q#b&9&9":;4<<BBC CGB_B_C499\,<<=>eq 	 a		!9:?R-=-==>		 		 KK,,55i95U	 #*3H
 	
U Ls   F-Fc                    | j                   rB|r?|dkD  r9t        j                  j                  j	                  | j                         |       yyyt        |   |||       y)a  Override PTL gradient clipping to support fused AdamW.

        PTL's AMP precision plugin refuses to clip gradients when the optimizer declares it handles unscaling internally
        (fused=True).  When fused is active we are on BF16 (no GradScaler) so ``clip_grad_norm_`` is correct.  For the
        non-fused path (FP16 + GradScaler or FP32) we delegate to ``super()`` to preserve scaler-aware unscaling.

        Args:
            optimizer: The current optimizer.
            gradient_clip_val: Maximum gradient norm.
            gradient_clip_algorithm: Clipping algorithm; forwarded to super()
                for the non-fused path.
        r   r   N)r  rI   nnutilsclip_grad_norm_r   r1   r   )rN   r   r   r   rQ   s       rR   r   z RFDETRModelModule.clip_gradients]  s^    $ $$ %6%:..t/@BST &;  G""3(? # rS   c                  
 |\  }}| j                  |      }| j                  j                  r[| j                  ||      
| j                  j                  t        
fd
D              }| j                  d|dt        |             t        j                  |D cg c]  }|d   	 c}      }| j                  ||      }	|	|dS c c}w )a*  Run forward pass and postprocess for one test step.

        Mirrors :meth:`validation_step` so ``COCOEvalCallback`` can accumulate results via ``on_test_batch_end`` when
        ``trainer.test()`` is called (e.g. from :class:`~rfdetr.training.callbacks.BestModelCallback` at end of
        training).

        Args:
            batch: Tuple of (NestedTensor samples, list of target dicts).
            batch_idx: Batch index within the test epoch.

        Returns:
            Dict with ``results`` (postprocessed predictions) and ``targets``.
        c              3  >   K   | ]  }|v s|   |   z    y wr   r   r   s     rR   r   z.RFDETRModelModule.test_step.<locals>.<genexpr>  r  r   z	test/lossT)r   r   r   r  )r;   r4   compute_test_lossrA   r   r   r   r   rI   r   rB   r  s             @@rR   	test_stepzRFDETRModelModule.test_stepy  s     !**W%..w8I..44K\i\\DHH[$$3w<HP[['!BQ!K.!BC
""7J7"w77 "Cs   Cc                    |\  }}t        j                         5  | j                  |      }ddd       t        j                  |D cg c]  }|d   	 c}      }| j	                  |      S # 1 sw Y   AxY wc c}w )a^  Run inference on a preprocessed batch and return postprocessed results.

        Args:
            batch: Tuple of (NestedTensor samples, list of target dicts).
            batch_idx: Batch index.
            dataloader_idx: Index of the predict dataloader.

        Returns:
            Postprocessed detection results from ``PostProcess``.
        Nr   )rI   rj   r;   r   rB   )	rN   rr   rs   dataloader_idxrv   r   r   r   r   s	            rR   predict_stepzRFDETRModelModule.predict_step  sl     !]]_ 	*jj)G	*[['!BQ!K.!BC
44	* 	*!Bs   A,A8,A5c                   d|v r1d|vr-|d   j                         D ci c]  \  }}d|z   | c}}|d<   d|v r#t        |d   | j                  j                         d|v r'|d   | _        t        j                  dt        d       yyc c}}w )	u  Auto-detect legacy formats and reconcile PE shapes at checkpoint load time.

        PTL calls this hook before applying ``checkpoint["state_dict"]`` to the module.  Three normalisation steps are
        applied in order:

        1. **Raw legacy format** — a ``*.pth`` file loaded directly by
           ``Trainer`` (e.g. via ``ckpt_path=``).  Recognised by the presence of ``"model"`` without ``"state_dict"``.
           The state dict is rewritten in-place with the ``"model."`` prefix so PTL can apply it normally.

        2. **Positional-embedding interpolation** — when the checkpoint was
           saved at a different image resolution than the current model, the DINOv2 ``position_embeddings`` tensor shape
           will mismatch. :func:`~rfdetr.models.weights.interpolate_position_embeddings` is called to bicubic-resize the
           PE to ``model_config.positional_encoding_size`` before PTL applies the state dict.  Regression fix for
           :issue:`998`.

        3. **Converted format** — a file produced by
           :func:`~rfdetr.training.checkpoint.convert_legacy_checkpoint` that already has ``"state_dict"`` but also
           carries ``"legacy_ema_state_dict"``.  The EMA weights are stashed on ``self._pending_legacy_ema_state`` for
           optional restoration by :class:`~rfdetr.training.callbacks.ema.RFDETREMACallback`.

        Note:
            This hook only fires on ``Trainer(ckpt_path=...)`` resume paths. Fresh-train bootstrap from a
            ``pretrain_weights`` checkpoint runs through :func:`~rfdetr.models.weights.load_pretrain_weights` during
            ``__init__`` instead — that helper performs its own PTL ``.ckpt`` normalisation (``state_dict`` → ``model``
            key, ``_orig_mod`` strip) and PE interpolation, so the two code paths intentionally do not share state.

        Args:
            checkpoint: Checkpoint dict passed in by PTL (mutated in-place).
        r;   
state_dictzmodel.legacy_ema_state_dictzCheckpoint contains legacy EMA weights (`legacy_ema_state_dict`). Add RFDETREMACallback to your trainer callbacks to restore them; without it the stashed weights will be ignored.r   )
stacklevelN)r   r   r3   positional_encoding_size_pending_legacy_ema_statewarningswarnUserWarning)rN   
checkpointr   r   s       rR   on_load_checkpointz$RFDETRModelModule.on_load_checkpoint  s    > j \%CDNwDWD]D]D_'`DAq1a'`J|$ :%+<(!!:: #j0-78O-PD*MMB  1 (as   B	c                :    | j                   j                  |       y)zReinitialize the detection head for a new class count.

        Args:
            num_classes: New number of classes (excluding background).
        N)r;   reinitialize_detection_head)rN   num_classess     rR   rI  z-RFDETRModelModule.reinitialize_detection_head  s     	

..{;rS   )r3   r   r4   r   r#  None)r#  rK  )rr   r   rs   r   r#  rK  )rr   r   rs   r   r#  ztorch.Tensor | dict[str, Any])r   dict[str, torch.Tensor]r   list[dict[str, torch.Tensor]]r#  z:tuple[dict[str, torch.Tensor], torch.Tensor, torch.Tensor])r   torch.Tensorr   rN  r#  rN  )rz   rN  r#  rK  )rs   r   r#  r5   )r   torch.optim.Optimizerr#  rK  )r   rM  r#  rM  )r   rN  r   rL  r   r   r#  rK  )rr   r   rs   r   r#  Dict[str, Any])r#  r5   )r#  rP  )NN)r   rO  r   zOptional[float]r   zOptional[str]r#  rK  )r   )rr   r   rs   r   r;  r   r#  r   )rF  zdict[str, Any]r#  rK  )rJ  r   r#  rK  )r   
__module____qualname____doc__r2   rY   r{   r   r   r   r   r   r   r   r   staticmethodr   r   r   r  propertyr  r1  r   r9  r<  rG  rI  __classcell__)rQ   s   @rR   r(   r(   *   sW   ?AJU206\^|#/(#/ /#/ 
D	#/J11 !1 
	1,h
>06
" 
 
## +#
 # 
#Jhh +h
 h 
h.82 
 
6>
F .215	( + "/	
 
8845"6p<rS   r(   ))rS  
__future__r   r   rh   rC  typingr   r   r   r   rI   torch.nn.functionalr3  
functionalrk   pytorch_lightningr   r	   rfdetr._namespacer
   rC   r   r   rfdetr.datasets.cocor   rfdetr.models.lwdetrr   r   rfdetr.models.weightsr   r   r   rfdetr.training.param_groupsr   rfdetr.utilities.loggerr   r>   r&   __annotations__r(   r   rS   rR   <module>rc     s    ; "    - -    > 5 2 ; U d d 7 .	 ! (&"
0 n 
x
< x
<rS   