
    ^jJ                      U d dl mZ d dlZd dlZd dlZd dlZ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 d dlmZ d dlmZ d dlmZmZmZmZmZ d dlZd dlZd dlZd dlmc m Z! d dl"Z"d d	l#m$Z$ d d
l%m&Z&m'Z' d dl(m)Z)m*Z* d dl+m,Z,m-Z- d dl.m/Z/m0Z0m1Z1 d dl2m3Z3 d dl4m5Z5m6Z6 d dl7m8Z8m9Z9 d dl:m;Z; d dl<m=Z=m>Z> d dl?m@Z@ erd dlAmBZBmCZC 	  ej                  d        e@       ZF ed      ZG ed      ZHdZIddgeIZJ eKddh      ZL eMd eID              ZNdeOd<   d ZPdeOd!<   d"ZQd#eOd$<   d%ZRd#eOd&<   	 	 	 	 	 	 	 	 	 	 d.d'ZSd/d(ZTd0d)ZUd1d*ZV G d+ d      ZWd2d,ZXd3d-ZYy# eE$ r Y w xY w)4    )annotationsN)defaultdict)Callable)copydeepcopywraps)Path)TYPE_CHECKINGAnyConcatenate	ParamSpecTypeVar)Image)COCO_CLASS_NAMESCOCO_CLASSES)download_pretrain_weightsget_model_cache_dir)ModelConfigTrainConfig)active_keypoint_countsinfer_coco_keypoint_schemainfer_yolo_keypoint_schema)is_valid_coco_dataset)REQUIRED_YOLO_YAML_FILESis_valid_yolo_dataset)ModelContext_build_model_context)is_main_process)_is_bg_first_schema&precision_cholesky_to_pixel_covariance)
get_logger
Detections	KeyPointshigh_P_R)
RFDETRBaseRFDETRKeypointPreviewRFDETRLargeRFDETRLargeDeprecatedRFDETRMedium
RFDETRNano	RFDETRSegRFDETRSeg2XLargeRFDETRSegLargeRFDETRSegMediumRFDETRSegNanoRFDETRSegPreviewRFDETRSegSmallRFDETRSegXLargeRFDETRSmallRFDETRr   r,   r/   c              #  2   K   | ]  }|t         vs|  y w)N)'_CHECKPOINT_MODEL_NAME_EXCLUDED_SYMBOLS).0class_symbols     V/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/detr.py	<genexpr>r>   N   s      >!Mt9tL>s   ztuple[str, ...]$_CHECKPOINT_MODEL_NAME_CLASS_SYMBOLS)RFDETRXLargeRFDETR2XLarge)_CHECKPOINT_PLUS_MODEL_NAME_CLASS_SYMBOLS))keypoint-previewr*   )zseg-2xlarger0   )zseg-xxlarger0   )z
seg-xlarger6   )z	seg-larger1   )z
seg-mediumr2   )z	seg-smallr5   )zseg-nanor3   )zseg-previewr4   )larger+   )mediumr-   )smallr7   )nanor.   )baser)   ztuple[tuple[str, str], ...]_CHECKPOINT_MODEL_MAP_ENTRIES))2xlargerA   )xxlargerA   )xlarger@   "_CHECKPOINT_PLUS_MODEL_MAP_ENTRIESc                P   	 | \  }}d|fd|ffD ]g  \  }}t        |t              r(t        d| dt	        |      j
                   d| d	      	 t        j                  |       |d
k  sZt        d| d       t        j                  |      t        j                  |      }}||z  d
k7  s||z  d
k7  rt        d| d| d| d| d	      ||fS # t         t        f$ r t        d| d      dw xY w# t         $ r* t        d| dt	        |      j
                   d| d	      dw xY w)u  Validate a user-supplied ``(height, width)`` shape tuple and return normalised plain-int dims.

    Args:
        shape: The raw value supplied by the caller (e.g. from ``export(shape=...)`` or
            ``predict(shape=...)``).  Must be a two-element sequence of positive integers (or integer-compatible types
            accepted by :func:`operator.index`).
        block_size: Required divisor for both dimensions.  Equals ``patch_size * num_windows``.
        patch_size: Backbone patch size — used only in error messages.
        num_windows: Number of attention windows — used only in error messages.

    Returns:
        A ``(height, width)`` tuple of plain Python :class:`int` values.

    Raises:
        ValueError: If ``shape`` cannot be unpacked as a two-element sequence, if either
            dimension is a bool, float, or other non-integer type, if either dimension is not positive, or if either
            dimension is not divisible by ``block_size``.
    zGshape must be a sequence of two positive integers (height, width), got .Nheightwidthzshape z must be an integer, got z (shape=z).r   z?shape must contain positive integers for height and width, got z-shape must have both dimensions divisible by  (patch_size= * num_windows=z), got )	TypeError
ValueError
isinstancebooltype__name__operatorindex)shape
block_size
patch_sizenum_windowsrP   rQ   dim_namedims           r=   _validate_shape_dimsrb   i   s   0y $V,w.>? 
k#c4 vhZ/HcI[I[H\\dejdmmopqq	NN3
 !8^_d^gghijj
k NN6*HNN5,AEF
a5:#5#:;J< H%,ok]'%RSU
 	
 5=) z" ybchbkklmntxxy  	
";DI<N<N;OxX]W``bc	s   C C2 C/23D%c                B   | t        |dd      } n[t        | t              st        | t              r| dk  rt	        d|       t        |dd      }|| |k7  rt	        | d|  d| d      t        | t              st        | t              r| dk  rt	        d|       | S )	u2  Resolve and validate the ``patch_size`` argument for :meth:`RFDETR.export` and :meth:`RFDETR.predict`.

    Args:
        patch_size: Value supplied by the caller, or ``None`` to read from ``model_config``.
        model_config: The model's configuration object.  Must expose ``patch_size`` as a
            positive integer attribute when ``patch_size`` is ``None`` or when a mismatch check is needed.
        caller: Name of the calling method (``"export"`` or ``"predict"``) — used in
            error messages to help the caller locate the problem.

    Returns:
        A validated, positive :class:`int` patch size.

    Raises:
        ValueError: If the resolved or provided ``patch_size`` is not a positive integer,
            or if a caller-provided value disagrees with ``model_config.patch_size``.
    Nr^      r   z+patch_size must be a positive integer, got z(patch_size=z5) does not match the instantiated model's patch_size=z`. Patch size is an architectural parameter; omit patch_size to use the model's configured value.)getattrrV   rW   intrU   )r^   model_configcallermodel_patch_sizes       r=   _resolve_patch_sizerj      s    " \<<
j$'z*c/Jj\]oJ:.YZZ"<tD'J:J,J(,zl 3./ 0GH 
 *d#:j#+F*XY/FznUVV    c                *   t        | dd      }t        | dd      }||t        |d      syt        |t              rt	        j
                  |      }t        |j                         d      }|'|j
                  |k7  r|j                  |      | _	        yyy)a  Move model weights to the target device recorded in *model_ctx*.

    ``_build_model_context`` intentionally keeps the ``nn.Module`` on CPU so that ``RFDETR.__init__`` does not
    initialise CUDA (which would prevent DDP strategies from forking in notebook environments).  This helper performs
    the deferred ``.to(device)`` on first use.

    It is safe to call on duck-typed stand-ins (e.g. ``SimpleNamespace``); the function silently returns when the
    expected attributes are missing.
    deviceNmodel
parameters)
re   hasattrrV   strtorchrm   nextro   torn   )	model_ctxtargetinnerfirst_params       r=   _move_model_context_to_devicery      s     Y$/FIw-E~ge\.J&#f%u'')40K;#5#5#?((6*	 $@rk   c                0     t               d fd       }|S )a  Decorate RF-DETR instance methods that require lazy model device placement.

    The wrapped method receives the same arguments and return value as the original method. Before calling it, the
    decorator moves ``self.model.model`` to ``self.model.device`` if the model context is available and the weights are
    still on a different device. This keeps public inference methods clean while preserving deferred CUDA initialization
    during ``RFDETR.__init__``.
    c                H    t        t        | dd               | g|i |S )Nrn   )ry   re   )selfargskwargsmethods      r=   wrapperz(_ensure_model_on_device.<locals>.wrapper   s)    %gdGT&BCd,T,V,,rk   )r|   r   r}   z_P.argsr~   z	_P.kwargsreturnr(   r   )r   r   s   ` r=   _ensure_model_on_devicer      s"     6]- - Nrk   c                  z   e Zd ZU dZg dZg dZdZeZde	d<   e
Zde	d<   d	 Zd
 Zd(dZed)d       Zed*d       Zd Zeddej,                  fdd	 	 	 	 	 	 	 	 	 d+d       Zd,dZed-d       Z	 	 	 	 	 	 	 	 	 	 	 	 	 d.dd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d/dZed0d       Zeddd1d       Zd2dZed3d       Zed3d       Z ed3d       Z!ed4d       Z"d5d Z#d6d!Z$d7d"Z%ed8d#       Z&d,d$Z' ejP                         e	 	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 	 	 d:d%              Z)	 	 d;	 	 	 	 	 	 	 	 	 	 	 d<d&Z*d=d'Z+y)>r8   zThe base RF-DETR class implements the core methods for training RF-DETR models, running inference on the models,
    optimising models, and uploading trained models for deployment.)g
ףp=
?gv/?gCl?)gZd;O?gy&1?g?Nztype[ModelConfig]_model_config_classztype[TrainConfig]_train_config_classc                    | j                   di || _        | j                          | j                  | j                        | _        t        t              | _        | j                  j                  dk7  rddl	m
} t        t        | j                  j                         || j                              D cg c]  \  }}|	 c}}| _        t        t        | j                  j                         || j                              D cg c]  \  }}|	 c}}| _        d | j                  _        d| _        d| _        d| _        d | _        d | _        d | _        d| _        y c c}}w c c}}w )N   r   )cycleF )get_model_configrg   maybe_download_pretrain_weights	get_modelrn   r   list	callbacksnum_channels	itertoolsr   ziprangemeansstdsinference_model_is_optimized_for_inference3_has_warned_about_not_being_optimized_for_inference_optimized_has_been_compiled_optimized_batch_size_optimized_resolution_optimized_dtype_optimized_inplace)r|   r~   r   _vals        r=   __init__zRFDETR.__init__   s$   1D11;F;,,.^^D$5$56
$T* ))Q.',/d6G6G6T6T0UW\]a]g]gWh,ij&!S#jDJ+.uT5F5F5S5S/TV[\`\e\eVf+ghChDI%)

"+0(CH@,1)%)"%)" $"' khs   7E E&c                   | j                   j                  }|yt        j                  j	                  |      sBt               }t        j                  |d       t        j                  j                  ||      }n4t        j                  t        j                  j	                  |      d       || j                   _        t        | j                   j                         y)uw  Download pre-trained weights if they are not already downloaded.

        Bare filenames (no directory component, e.g. ``rf-detr-base.pth``) are resolved to the model cache directory —
        set the ``RF_HOME`` environment variable to override the location (default: ``~/.roboflow/models``). Resolution
        happens in ``ModelConfig.expand_path`` for explicitly-provided values, and here as a fallback for field defaults
        (which Pydantic does not validate by default).

        Paths that already contain a directory component are used as-is; the parent directory is created if it does not
        yet exist.
        NTexist_ok)	rg   pretrain_weightsospathdirnamer   makedirsjoinr   )r|   r   	cache_dirs      r=   r   z&RFDETR.maybe_download_pretrain_weights  s      ,,==#ww/0+-IKK	D1!ww||I7GHKK(89DI-=*!$"3"3"D"DErk   c                &     | j                   di |S )z8Retrieve the configuration parameters used by the model.r   )r   r|   r~   s     r=   r   zRFDETR.get_model_config      't''1&11rk   c                   ddl m} d}i }g }ddlm} |rE	 ddlmc m} t        D ]  }	t        ||	      }
|
||	<    t        D 	cg c]  \  }}	|||	   f }}}	d}t        j                  |dd      }|d	   }t        |      D ci c]-  }|j                  d
      rt        ||      }t        |d|      |/ }}}t         D 	ci c]  }	|	||	   
 }}	t"        D 	cg c]  \  }}	|j                  d      r|||	   f }}}	t"        D 	cg c]  \  }}	d|v r|||	   f }}}	t"        D 	cg c]!  \  }}	|j                  d      sd|vr|||	   f# }}}	||z   |z   |z   }t%        |      }|r|j'                  |       |j)                  d      }d}t+        |t,              r$|j/                         }|r|j)                  |      }nd}t+        |t$              r8t-        |j)                  dd            j/                         j1                         }n2t-        t        |dd            j/                         j1                         }d}|dv rBt2        j4                  j7                  t3        j8                  |            j1                         }d}||t        v }d|v xr
 d|vxr d|v}|s/|s|r+ddlm} t=        d|d|d|j?                  d      z         |D ]  \  }} ||v s| } n |r.|,t@        jC                  d|t        |dtE        |            |       |tG        d|d|d|d      t+        |t$              r|j)                  d      }!nt        |dd      }!i }"tI               }#t        |dd      }$i }%t        |$d d      }&t+        |&t$              r|&}%nt        |$d!d      }'t+        |'t$              r|'}%|j)                  d"      }(t+        |(t$              r;|(jK                         D ](  \  })}*|)dk(  r|%r|)|%v s|*|"|)<   |#jM                  |)       * |!d|vr|!|"d<   |#jM                  d       |j)                  d#      xs i }+|+sgd$|v rcd%},i }+|d$   jK                         D ]I  \  }-}.|-j                  |,      s|-tO        |,      d })|)j                  d&      r|)tO        d&      d })|.|+|)<   K |+rPd'|vr|%rd'|%v r|+j)                  d(      }/t+        |/t        jP                        r|/jR                  d)k(  ry|/jU                  d*+      jW                         D 0cg c]  }0tY        |0       }1}0|"j)                  d'      }2|1|2k7  rt@        j[                  d,|2|1       |1|"d'<   |#jM                  d'       d|vr|+j)                  d-      }3t+        |3t        jP                        rd|3jR                  d)k(  rU|3j\                  d   d*z
  }4|"j)                  d      }5|4|5k7  rt@        j[                  d.|5|4       |4|"d<   |#jM                  d       |"j'                  |       t-        |      |"d<   |#tI        |      z
  }6 |d2i |"}7|6r^t        |7d"d      }8t        |8d/d      }9|9t        |8d0d      }9|9|9j_                  |6       d|6v rdt        |8d/tI                     vsJ d1       |7S c c}	}w # t        $ r}|j                  dvr Y d}~]d}~ww xY wc c}}w c c}	w c c}	}w c c}	}w c c}	}w c c}0w )3u^  Load an RF-DETR model from a training checkpoint, automatically inferring the model class.

        The correct subclass is resolved in order of preference:

        1. ``model_name`` key in the checkpoint (written by the PTL training
           stack since v1.7.0).
        2. ``pretrain_weights`` field in the checkpoint's ``args`` entry
           (legacy fallback for older checkpoints).
        3. The **filename** of *path* itself, used as a last resort when
           ``pretrain_weights`` is absent or an unset-like sentinel value
           (empty string, ``"none"``, or ``"null"``).  Starter weights
           published by Roboflow store ``pretrain_weights="none"`` in their
           ``args``; passing the canonical filename (e.g.
           ``rf-detr-small.pth``) lets ``from_checkpoint`` infer the class
           automatically.

        Both legacy ``argparse.Namespace`` checkpoints (produced by ``engine.py``) and dict-style checkpoints (produced
        by the PTL training stack) are supported.

        Args:
            path: Path to a checkpoint file (e.g. ``checkpoint_best_total.pth``).
            **kwargs: Additional keyword arguments forwarded to the model
                constructor (e.g. ``accept_platform_model_license=True`` for XLarge / 2XLarge models).

                ``num_classes`` is resolved in this priority order:

                1. Explicit caller kwarg — always wins.
                2. Weight inference from ``class_embed.weight`` shape in the checkpoint
                   (``shape[0] - 1``, since the head includes a background class). This
                   overrides a stale ``model_config`` value written before fine-tuning
                   changed the class count.
                3. ``saved_model_config["num_classes"]`` from the checkpoint's
                   ``model_config`` entry — may be stale for older checkpoints.
                4. Legacy ``args["num_classes"]`` dict entry.
                5. Constructor default.

                In cases 2–5 the field is not recorded as a user-set override, so
                :meth:`train` can still adapt the detection head to the training
                dataset's class count.  Pass an explicit ``num_classes=N`` to pin
                the head and prevent adaptation.

        Returns:
            An instance of the appropriate :class:`RFDETR` subclass loaded from the checkpoint.

        Warning:
            This method calls ``torch.load`` with ``weights_only=False``, which
            unpickles arbitrary Python objects. Only load checkpoints from trusted sources.

        Raises:
            FileNotFoundError: If *path* does not exist.
            OSError: If *path* exists but cannot be read.
            KeyError: If the checkpoint does not contain an ``"args"`` key.
            ValueError: If the model class cannot be inferred from ``model_name``,
                ``pretrain_weights``, or the checkpoint filename.

        Examples:
            >>> model = RFDETR.from_checkpoint("checkpoint_best_total.pth")  # doctest: +SKIP
            >>> model = RFDETRSmall.from_checkpoint("checkpoint_best_total.pth")  # doctest: +SKIP
        r   NF)_IS_RFDETR_PLUS_AVAILABLET>   rfdetr_plus.modelsrfdetr_pluscpu)map_locationweights_onlyr}   r8   rY   zseg-keypoint
model_name r   >   r   nonenullrL   rC   )_INSTALL_MSGzCheckpoint model_name=z, pretrain_weights=z# requires the rfdetr_plus package. zplatform model downloads)namezQpretrain_weights unset in checkpoint %r; inferred model class %s from filename %rz/Could not infer model class from checkpoint at z (model_name=z/). Please instantiate the model class directly.num_classesr   model_fields
__fields__rg   rn   
state_dictzmodel.z
_orig_mod.num_keypoints_per_class_kp_active_mask      )ra   u   from_checkpoint: overriding num_keypoints_per_class %s → %s (inferred from _kp_active_mask; saved model_config may be stale).zclass_embed.weightuv   from_checkpoint: overriding num_classes %s → %s (inferred from class_embed.weight; saved model_config may be stale).model_fields_set__pydantic_fields_set__u   num_classes still in model_fields_set after checkpoint load; Pydantic may return a snapshot rather than the live backing set — switch to model_construct(_fields_set=...) for Pydantic v3 compatibility.r   )0rfdetr.variantsvariantsrfdetr.platformr   rfdetr.platform.modelsplatformmodelsrB   re   rM   ModuleNotFoundErrorr   rr   loaddir
startswithr?   rI   dictupdategetrV   rq   striplowerr   r   basenamefspathr   ImportErrorformatloggerinforeprrU   setitemsaddlenTensorndimsumtolistrf   debugr\   difference_update):clsr   r~   rfdetr_variants_plus_available_plus_symbols_plus_entriesr   platform_modelsr<   plus_objr   exckptr}   symbolvariant_obj_variant_name_to_class_variant_symbols_seg_map_keypoint_map	_base_map
_model_map	_name_mapsaved_model_name	model_clsnormalized_nameweights_name_filename_fallbackplus_by_model_nameplus_by_weights_namer   klassr   constructor_kwargscheckpoint_config_keysr   
_mc_fields_mc_model_fields
_mc_legacysaved_model_configkeyvalue_ckpt_weights_pfxkv_kp_maskn_inferred_kp_current_kp
_ce_weight_inferred_nc_current_nccheckpoint_derived_keysrn   loaded_config
fields_sets:                                                             r=   from_checkpointzRFDETR.from_checkpoint  s   | 	2138:=$@@$M ;L&EH2:M,/; Su!<ND,T=67! ! #'  %zz$UQVWF| o.;
  * ' @ KV4kA4;
 ;
 Tx5
COL0>>5
 5
 'D4
"lv& #L124
 4
 'D9
"lT! #L129
 9
 'D5
"l??6*z/E #L125
	 5

 6>5MP]5]`i5i
 .22B-C	]+88L1)-	&,.446O%MM/:	 O dD!txx(:B?@FFHNNPLwt-?DEKKMSSUL #//77++BIIdO<BBDL!% "14]!]L(rV<-GrL^frLr ! #(:>R8!,-=,@@ST`Sc d, -/;/B/BHb/B/cd 
  * e<' %I
 "i&;gIz4	?C 	 A$ J/22ElEU V?@  dD!&*hh}&=K!$t<K-/+.5 &i1FM%'
"#6M&-)J !4lDIJ*d+'
!XXn5($/0668 4
U,,!SJ%6.3&s+*..s34 "}F'B0;}-"&&}5 )-(9(?R!5DM\*002 +1<<%CIK.C~~l3!#l"3"56)*M#&+  )6
NgkuNu(,,->?h5(--1:L4<LLQL4G4N4N4P#QqCF#QL#Q"4"8"89R"SK#{2`'(	 EQ&'@A*../HI F**../CD
j%,,7JOOq<P#-#3#3A#6#:L"4"8"8"GK#{2c'(	 9E&}5*..}=!!&) 25T-. #93v;"F/./"#E>4@M !0BDIJ!$]4MtT
%,,-DE  77$GMCUWZW\,]] `] I! ' 77"GG H;
5

4

9

5
F $RsM   .Z ZZ 2Z?["[
[)&[[Z 	Z<"Z77Z<c                   | y	 t        j                  |       }|j
                  dk(  ry|j
                  dk(  rd|j                  |j                  gfS dfS |j
                  d	k(  rd	|j                  |j                  gfS dfS t        j                  d
|j
                  dt        d       y# t        t        t        f$ r}t        d| d      |d}~ww xY w)a  Map a torch-style device specifier to PTL ``accelerator``/``devices`` kwargs.

        Args:
            device: A device specifier accepted by ``torch.device``.

        Returns:
            ``(accelerator, devices)`` where ``devices`` is ``None`` unless an explicit device index is provided (for
            example ``cuda:1``).

        Raises:
            ValueError: If ``device`` is not a valid torch device specifier.
        NNNz&Invalid device specifier for train(): zE. Expected values like 'cpu', 'cuda', 'cuda:0', or torch.device(...).r   )r   NcudagpumpszDevice type z is not explicitly mapped to a PyTorch Lightning accelerator; falling back to PTL auto-detection. Training may use an unexpected device.r   
stacklevel)
rr   rm   rT   rU   RuntimeErrorrX   r[   warningswarnUserWarning)rm   resolved_deviceexcs      r=   _resolve_trainer_device_kwargsz%RFDETR._resolve_trainer_device_kwargsP  s    >	#ll62O 5(6)_5J5J5V?001``\```5(_5J5J5V?001``\```?//2 3f f		
 ' :|4 	8
 CV V 	s   B/ /CCCc                Z   	 ddl m}m}m} ddlm} |j                  dd      }|r5t        |j                               rt        j                  dt        d	
       |j                  dd      }t         j#                  |      \  }	}
d|v r-t        j                  dt        d	
       |j                  d       t%        |j                  dd            }|rt        j                  dt        d	
       |j                  dd      }|t'        |t$              rt)        d      	 t+        j,                  |      }|dk  rt)        d      | j0                  j2                  | j0                  j4                  z  }||z  dk7  rCt)        d| d| j0                  j2                   d| j0                  j4                   d| d| d      | j0                  j6                  }| j0                  j8                  | j0                  j2                  z  }||k(  r+|| j0                  j2                  z  }|| j0                  _        n|}|| j0                  _        t;        | d      rr| j<                  ft;        | j<                  d      r|| j<                  _        t?        | j<                  dd      }|&t;        |d      r||_        t;        |d      r||_         | j@                  d5i |}|jB                  dk(  rtE        | j<                          || j<                  | j0                  |      }|jF                  |_!        |jH                  |_%        tL        jO                  d|jB                  |jJ                  |jP                         tS        |       jT                  | j0                  _+        t?        |dd      }|r"| jY                  |       | j[                  |        || j0                  |      } || j0                  |      }|j\                  rt^        j`                  jc                  d d!      d!k(  r~	 dd"l2m3} |ji                  d#       tk        |jl                        d$z  } ||jo                         |d%&      jq                           ||js                         |d'&      jq                          d+|	i}|
|
|d,<    ||| j0                  fi |}|jy                  |||jz                  xs d-       |j<                  | j<                  _        | j}                          t?        |d.d      }||| j<                  _?        n t?        |d.d      }||| j<                  _?        t               r|j                         | j0                  j                         | j0                  j                  jT                  | j<                  j~                  | j<                  j~                  rt        | j<                  j~                        ndd/}	 t_        j                  |jl                  d)0       t        t^        j                  j                  |jl                  d1      d2      5 }t        j                  ||d	t        3       ddd       yy# t        $ r9}|j                  r|j                  j                  d      r t        d      |d}~ww xY w# t.        $ r}t)        d      |d}~ww xY w# tt        $ r tL        jw                  d(d)*       Y Pw xY w# 1 sw Y   yxY w# t        $ r+}tL        jw                  d4|jl                  |       Y d}~yd}~ww xY w)6u
  Train an RF-DETR model via the PyTorch Lightning stack.

        All keyword arguments are forwarded to :meth:`get_train_config` to build a :class:`~rfdetr.config.TrainConfig`.
        Several kwargs are absorbed and handled specially so that existing call-sites do not break:

        * ``resolution`` — updates the model's input resolution by mutating
          :attr:`model_config.resolution` in place before the train config is built. This change persists on
          :attr:`model_config` after :meth:`train` returns. The value must be a positive integer divisible by
          ``patch_size * num_windows`` for the model variant; a :class:`ValueError` is raised otherwise.
          :attr:`model_config.positional_encoding_size` is also updated when the config derives it formulaically (``PE
          == resolution // patch_size``); configs with a pretrained-specific PE value (e.g. ``RFDETRBase`` uses DINOv2's
          PE=37 at 560 px) are left unchanged to preserve checkpoint compatibility.
        * ``device`` — normalized via :class:`torch.device` and mapped to PyTorch
          Lightning trainer arguments. ``"cpu"`` becomes ``accelerator="cpu"``; ``"cuda"`` and ``"cuda:N"`` become
          ``accelerator="gpu"`` and optionally ``devices=[N]``; ``"mps"`` becomes ``accelerator="mps"``. Other valid
          torch device types fall back to PTL auto-detection and emit a :class:`UserWarning`.
        * ``callbacks`` — if the dict contains any non-empty lists a
          :class:`DeprecationWarning` is emitted; the dict is then discarded. Use PTL
          :class:`~pytorch_lightning.Callback` objects passed via :func:`~rfdetr.training.build_trainer` instead.
        * ``start_epoch`` — emits :class:`DeprecationWarning` and is dropped.
        * ``do_benchmark`` — emits :class:`DeprecationWarning` and is dropped.
        * ``notes`` — optional user-defined metadata (string, dict, list, or
          any JSON-serialisable value) stored under the ``"notes"`` key in every ``.pth`` checkpoint produced during
          training.  The value is also available inside ``args["notes"]`` for full provenance.  Pass the same value to
          :meth:`export` to embed it in the ONNX file as well.

        After training completes the underlying ``nn.Module`` is synced back onto ``self.model.model`` so that
        :meth:`predict` and :meth:`export` continue to work without reloading the checkpoint.

        Raises:
            ImportError: If training dependencies are not installed. Install with
                ``pip install "rfdetr[train,loggers]"``.
            ValueError: If ``resolution`` is not a positive integer or is not
                divisible by ``patch_size * num_windows`` for the model variant.
        r   )RFDETRDataModuleRFDETRModelModulebuild_trainer)resolve_auto_batch_configzrfdetr.zqRF-DETR training dependencies are missing. Install them with `pip install "rfdetr[train,loggers]"` and try again.Nr   zCustom callbacks dict is not forwarded to PTL. Deprecated since v1.7.0, will be removed in v1.9.0. Use PTL Callback objects instead.r   r  rm   start_epochzo`start_epoch` is deprecated since v1.7.0 and will be removed in v1.9.0; PTL resumes automatically via `resume`.do_benchmarkFzn`do_benchmark` in `.train()` is deprecated since v1.7.0 and will be removed in v1.9.0; use `rfdetr benchmark`.
resolutionz%resolution must be a positive integerzresolution=z! is not divisible by patch_size (z) * num_windows (z) = z,. Choose a resolution that is a multiple of rO   rn   r}   positional_encoding_sizeauto)model_contextrg   train_configz][auto-batch] resolved train config: batch_size=%s grad_accum_steps=%s effective_batch_size=%sdataset_dir
LOCAL_RANK0)DatasetGridSaverfitdataset_gridstrain)dataset_typer   zBFailed to save dataset grids; training will continue without them.T)exc_infoacceleratordevices)	ckpt_pathclass_names)r/  rg   model_config_typer<  r   r   ztraining_config.jsonw)indentdefaultz-Could not save training_config.json to %s: %sr   )Lrfdetr.trainingr%  r&  r'  rfdetr.training.auto_batchr(  r   r   r   r   popanyvaluesr  r  DeprecationWarningr8   r#  rW   rV   rU   rZ   r[   rT   rg   r^   r_   r,  r+  rp   rn   re   get_train_config
batch_sizery   safe_micro_batchrecommended_grad_accum_stepsgrad_accum_stepsr   r   effective_batch_sizerX   rY   r   #_align_keypoint_schema_from_dataset_align_num_classes_from_datasetsave_dataset_gridsr   environr   rfdetr.datasets.save_gridsr3  setupr
   
output_dirtrain_dataloader	save_gridval_dataloader	Exceptionwarningr4  resumeremove_optimized_modelr<  r   
model_dump	__class__r   r   openr   r   jsondumprq   OSError) r|   r~   r%  r&  r'  r(  r"  callbacks_dict_device_accelerator_devicesrun_benchmark_resolutionerrorr]   _current_pe_derived_penew_pe
model_argsconfig
auto_batchr0  module
datamoduler3  grids_output_dirtrainer_kwargstrainerconfig_class_namesdataset_class_namescomplete_configfs                                    r=   r6  zRFDETR.trainw  s   P	ZZL  K6c."7"7"9:MM4 # **Xt,!'!F!Fw!Oh F"MM:"	 JJ}% VZZ>?MM*"	 jjt4"+t, !HIIU&nn[9 a !HII**558I8I8U8UUJZ'1, !+ /##'#4#4#?#?"@ A))556d:, GAAKAO  ++DDK++66$:K:K:V:VVKk)$(9(9(D(DD=C!!: %+6D( tW%$***@4::|4,7DJJ)$TZZ>
)z<80;
-z+EF>D
;&&&00& *$**52"jj!..#J
 !+ ; ;F&0&M&MF#KKo!!''//	 (,Dz':':$
 fmT:44V<00="4#4#4f=%d&7&7@
 $$c)Jc)QG  '#'(9(9#:_#L  !<!<!>@P_fgqqs !:!:!<>N]bcmmo (6(0N9%(9(9L^LFJ&--2G4H "<<

 	##%$V]DA)%7DJJ"")*mT"J".)<

&  & 1 1 3 $ 1 1 < < >%)%6%6%@%@%I%I#zz55>Bjj>T>Ts4::#9#9:Z[OhF--="'',,v'8'8:PQSVW I[\IIoqCHI I M # 	 xxCHH//	:Y 	n  U !HIuTUf  X!  LI I hNPVPaPacfgghsy   Y!  Z& A=[ $A[6 9[*[6 !	Z#*4ZZ#&	[ /Z;;[  ['&['*[3/[6 3[6 6	\*?!\%%\*Tr   F)inplacec                  t        |t              r	 t        t        |      }t        |t        j                        st        dt        |            |j                  st        d|       |r|rt        d      | j                          | j                  j                  t        d      | j                  j                  }|j                  dk(  rt        j                  j                  |      nt        j                          }	 |5  |r| j                  j                  nt#        | j                  j                        }|j%                          |j'                          |j)                  |      }|rt        j*                  j-                  |t        j.                  || j0                  j2                  | j                  j4                  | j                  j4                  | j                  j                  |            }d	| _        || _        || j                  _        || _        |rd| j                  _        | j                  j4                  | _        d	| _         || _!        ddd       y# t        $ r t        d|      dw xY w# 1 sw Y   yxY w# tD        $ r@ t        jF                  tD              5  | j                          ddd        # 1 sw Y    xY ww xY w)
u-  Optimize the model for inference with optional JIT compilation and dtype casting.

        Operations are wrapped in the correct CUDA device context to prevent context leaks on multi-GPU setups. When
        ``compile=True`` the model is traced with ``torch.jit.trace`` using a dummy input of ``batch_size`` images at
        the model's current resolution. By default, optimization deep-copies the loaded model before exporting it so the
        original module remains available. Set ``inplace=True`` for memory-constrained inference-only deployments; this
        exports the loaded module itself, may cast it to ``dtype``, and clears ``model.model`` after optimization
        succeeds. In-place optimization is destructive: :meth:`remove_optimized_model` becomes a no-op (issues
        :class:`UserWarning`), and :meth:`export` raises :class:`RuntimeError`. Create or reload a new ``RFDETR``
        instance to recover the original model.

        If ``inplace=True`` and the underlying ``export()`` call mutates the module before raising (e.g. setting
        internal flags and swapping ``forward``), the exception handler resets RFDETR wrapper flags to the unoptimized
        state but cannot undo changes made inside ``export()``. Create a new RFDETR instance for reliable inference
        after such a failure.

        Args:
            compile: If ``True``, trace the model with ``torch.jit.trace`` to obtain
                a JIT-compiled ``ScriptModule``. Set to ``False`` for broader compatibility (e.g. models with dynamic
                control flow).
            batch_size: Number of images the traced model will be optimized for. Ignored when ``compile=False``.
            dtype: Target floating-point dtype for the inference model. Accepts a
                ``torch.dtype`` directly (e.g. ``torch.float16``) or its string name (e.g. ``"float16"``). Defaults to
                ``torch.float32``. When ``dtype`` differs from the model's current dtype, ``to()`` transiently
                allocates both old and new parameter tensors simultaneously; peak memory during optimization is
                approximately 1.5× the model weight size rather than 1×.
            inplace: If ``True``, optimize ``model.model`` directly instead of deep-copying it. This is a destructive,
                inference-only path because ``export()`` mutates the module and dtype casting mutates its parameters.
                Requires ``compile=False``. With the default ``dtype=torch.float32``, the dtype cast is a no-op, so
                memory savings come only from clearing the base model reference rather than from dtype reduction.

        Raises:
            TypeError: If ``dtype`` is not a ``torch.dtype``, or if ``dtype`` is a
                string that does not correspond to a valid ``torch.dtype`` attribute.
            ValueError: If ``dtype`` is not a floating-point dtype, or if ``inplace=True`` is used with
                ``compile=True``.
            RuntimeError: If the base model has already been cleared by a previous inplace optimization.

        Examples:
            >>> from types import SimpleNamespace
            >>> import torch
            >>> class _TinyModel(torch.nn.Module):
            ...     def __init__(self):
            ...         super().__init__()
            ...         self.linear = torch.nn.Linear(1, 1)
            ...     def forward(self, x):
            ...         return {"pred_boxes": self.linear(x[:, :1, :1, :1].squeeze(-1).squeeze(-1))}
            ...     def export(self):
            ...         return None
            >>> class _TinyContext:
            ...     def __init__(self):
            ...         self.device = torch.device("cpu")
            ...         self.resolution = 28
            ...         self.model = _TinyModel()
            ...         self.inference_model = None
            >>> model = object.__new__(RFDETR)
            >>> model.model_config = SimpleNamespace(num_channels=3)
            >>> model.model = _TinyContext()
            >>> model._is_optimized_for_inference = False
            >>> model._has_warned_about_not_being_optimized_for_inference = False
            >>> model._optimized_has_been_compiled = False
            >>> model._optimized_batch_size = None
            >>> model._optimized_resolution = None
            >>> model._optimized_dtype = None
            >>> model._optimized_inplace = False
            >>> # Standard (non-inplace) optimization — reversible:
            >>> model.optimize_for_inference(compile=False)
            >>> model._is_optimized_for_inference
            True
            >>> model._optimized_inplace
            False
            >>> model.remove_optimized_model()
            >>> model._is_optimized_for_inference
            False
            >>> # Inplace optimization — destructive, cannot be reversed:
            >>> model.optimize_for_inference(compile=False, dtype="float16", inplace=True)
            >>> model._is_optimized_for_inference
            True
            >>> model._optimized_dtype
            torch.float16
            >>> model._optimized_inplace
            True
        z=dtype must be a torch.dtype or a string name of a dtype, got NzFdtype must be a floating-point torch.dtype or string name of one, got a  optimize_for_inference(inplace=True) requires compile=False. torch.jit.trace retains references to the original parameter storage in the returned ScriptModule, so setting model.model=None would not free the weight tensors and inplace=True would not reduce memory usage.z|Cannot optimize: the base model has been cleared by a previous inplace optimization. Create or reload a new RFDETR instance.r  dtype)rm   rz  T)$rV   rq   re   rr   AttributeErrorrT   rz  rX   is_floating_pointrU   rZ  rn   r  rm   r  
contextlibnullcontextr   evalexportrt   jittracerandnrg   r   r+  r   r   r   r   r   r   r   rW  suppress)r|   compilerH  rz  rw  rm   cuda_ctxr   s           r=   optimize_for_inferencezRFDETR.optimize_for_inferenceW  s   x eS!uu- %-[\`af\g[jkll&&efkelmnnw>  	##%::#: 
 ""06v0E5::$$V,:KaKaKc'	 !.6=$**"2"28DJJL\L\C]$$&&&("1"4"45"4"A&+iioo'& --:: JJ11 JJ11#'::#4#4"'
'O 9=D51;D. .=

*
 +2''+DJJ$-1ZZ-B-B*370(-%C!. !.7 " u"_`e_h ijpttu6!. !.D  	$$Y/ .++-..		sN   I( J EJJ (JJ	J J "K2K	KK	Kc                    t        | dd      rt        j                  dt        d       yd| j                  _        d| _        d| _        d| _        d| _	        d| _
        d| _        y)u  Remove the optimized inference model and reset all optimization flags.

        Clears ``model.inference_model`` and resets all internal state set by :meth:`optimize_for_inference`. Safe to
        call even if the model has not been optimized. When the model was optimized with ``inplace=True``, this method
        issues a :class:`UserWarning` and returns without modifying state — the original module cannot be restored
        because ``export()`` and dtype casting mutate it; create or reload a new ``RFDETR`` instance instead.

        Examples:
            >>> from types import SimpleNamespace
            >>> import torch
            >>> class _TinyModel(torch.nn.Module):
            ...     def __init__(self):
            ...         super().__init__()
            ...         self.linear = torch.nn.Linear(1, 1)
            ...     def forward(self, x):
            ...         return {"pred_boxes": self.linear(x[:, :1, :1, :1].squeeze(-1).squeeze(-1))}
            ...     def export(self):
            ...         return None
            >>> class _TinyContext:
            ...     def __init__(self):
            ...         self.device = torch.device("cpu")
            ...         self.resolution = 28
            ...         self.model = _TinyModel()
            ...         self.inference_model = None
            >>> model = object.__new__(RFDETR)
            >>> model.model_config = SimpleNamespace(num_channels=3)
            >>> model.model = _TinyContext()
            >>> model._is_optimized_for_inference = False
            >>> model._has_warned_about_not_being_optimized_for_inference = False
            >>> model._optimized_has_been_compiled = False
            >>> model._optimized_batch_size = None
            >>> model._optimized_resolution = None
            >>> model._optimized_dtype = None
            >>> model._optimized_inplace = False
            >>> model.optimize_for_inference(compile=False)
            >>> model.remove_optimized_model()
            >>> model._is_optimized_for_inference
            False
        r   Fu   remove_optimized_model() has no effect after inplace optimization — the original model cannot be restored because export() and dtype casting mutate it. Create or reload a new RFDETR instance instead.r   r  N)re   r  r  r   rn   r   r   r   r   r   r   r   r|   s    r=   rZ  zRFDETR.remove_optimized_model  sm    P 4-u5MMB  %)

"+0(,1)%)"%)" $"'rk   c                    t        | dd      S )a  Whether the model was optimized with ``inplace=True``.

        Returns ``True`` after a successful :meth:`optimize_for_inference` call with ``inplace=True``,
        meaning the base model has been cleared and :meth:`remove_optimized_model` is a no-op.

        Examples:
            >>> from types import SimpleNamespace
            >>> import torch
            >>> class _TinyModel(torch.nn.Module):
            ...     def __init__(self):
            ...         super().__init__()
            ...         self.linear = torch.nn.Linear(1, 1)
            ...     def forward(self, x):
            ...         return {"pred_boxes": self.linear(x[:, :1, :1, :1].squeeze(-1).squeeze(-1))}
            ...     def export(self):
            ...         return None
            >>> class _TinyContext:
            ...     def __init__(self):
            ...         self.device = torch.device("cpu")
            ...         self.resolution = 28
            ...         self.model = _TinyModel()
            ...         self.inference_model = None
            >>> model = object.__new__(RFDETR)
            >>> model.model_config = SimpleNamespace(num_channels=3)
            >>> model.model = _TinyContext()
            >>> model._is_optimized_for_inference = False
            >>> model._has_warned_about_not_being_optimized_for_inference = False
            >>> model._optimized_has_been_compiled = False
            >>> model._optimized_batch_size = None
            >>> model._optimized_resolution = None
            >>> model._optimized_dtype = None
            >>> model._optimized_inplace = False
            >>> model.is_optimized_inplace
            False
            >>> model.optimize_for_inference(compile=False, inplace=True)
            >>> model.is_optimized_inplace
            True
        r   F)re   r  s    r=   is_optimized_inplacezRFDETR.is_optimized_inplace2  s    P t1599rk   )notesc                  t         j                  d       d}|
|vrt        d|
d|       	 ddlm}m} | j                  j                  }t        | dd	      s| j                  j                  t        d      | j                  j                  j                  d      | j                  _        t        | j                  j                        }|j                  |       	 t        j                  |d       t!        |      }t#        |	| j$                  d      }	t        | j$                  dd      }t'        |t(              st'        |t*              r|dk  rt        d|      |	|z  }|f| j                  j,                  | j                  j,                  f}|d   |z  dk7  r=t        d| j                  j,                   d| d|	 d| d| d      t/        |||	|      } |||||| j$                  j0                        j                  |      }dg}|rdg}n:| j$                  j2                  rg d}n| j$                  j4                  rg d}nddg}|r||z   D ci c]  }|dd i	 }}nd
}|j7                          t9        j:                         5  |r, ||      }t         j=                  d!|j>                          n_| j$                  j2                  r ||      }|d"   }|d#   }|d$   } t'        | t8        j@                        r=t         j=                  d%|j>                   d&|j>                   d'| j>                          nt         j=                  d%|j>                   d&|j>                          n| j$                  j4                  rT ||      }|d"   }|d#   }|d(   }!t         j=                  d%|j>                   d&|j>                   d)|!j>                          nA ||      }|d"   }|d#   }t         j=                  d%|j>                   d&|j>                          d
d
d
       |jC                          |jC                         } |tE        |      ||||||||t        | d*d
      |+      }"t         j                  d,|"        |
d-k(  rtG        jH                  d.tJ        d/0       	 dd1l&m'}#  |#|"tE        |      |||rd3nd4||5      }$t         j                  d6|$        |$| j                  j                  j                  |      | j                  _        S t         j                  d7       t!        |"      | j                  j                  j                  |      | j                  _        S # t        $ r t         j                  d        w xY wc c}w # 1 sw Y   wxY w# t        $ r t         j                  d2        w xY w# | j                  j                  j                  |      | j                  _        w xY w)8u  Export the trained model to ONNX or TFLite format.

        See the `export documentation <https://rfdetr.roboflow.com/learn/export/>`_ for more information.

        Args:
            output_dir: Directory to write the exported model to.
            infer_dir: Optional directory of sample images for dynamic-axes inference.
            backbone_only: Export only the backbone (feature extractor).
            opset_version: ONNX opset version to target.
            verbose: Print export progress information.
            shape: ``(height, width)`` tuple; defaults to square at model resolution.
                Both dimensions must be divisible by ``patch_size * num_windows``.
            batch_size: Static batch size to bake into the ONNX graph.
            dynamic_batch: If True, export with a dynamic batch dimension
                so the ONNX model accepts variable batch sizes at runtime.
            patch_size: Backbone patch size. Defaults to the value stored in
                ``model_config.patch_size`` (typically 14 or 16). When provided explicitly it must match the
                instantiated model's patch size. Shape divisibility is validated against ``patch_size * num_windows``.
            format: Export format — ``"onnx"`` (default) or ``"tflite"``.
                When ``"tflite"`` is selected the model is first exported to ONNX then converted to TFLite via
                ``onnx2tf``.  Requires ``pip install rfdetr[onnx,tflite]``.

                .. warning::
                    TFLite export is experimental and subject to change; upstream dependency instabilities (``onnx2tf``,
                    ``ai_edge_litert``) may affect results.
            quantization: TFLite quantization mode (ignored when
                ``format="onnx"``).  One of ``None``, ``"fp32"``, ``"fp16"``, ``"int8"``.  ``None`` / ``"fp32"`` /
                ``"fp16"`` produce FP32 + FP16 ``.tflite`` files; ``"int8"`` additionally produces an INT8-quantized
                model.
            calibration_data: Representative images for INT8 calibration and ``onnx2tf`` output validation.  Accepts:

                * ``None`` — auto-generate random data (sufficient for fp32/fp16; warns for int8).
                * A **directory path** (``str``) containing JPEG/PNG
                  images — the converter automatically loads, resizes, and prepares them.  This is the simplest
                  approach.
                * A path (``str``) to a ``.npy`` file of shape ``(N, H, W, 3)``, dtype float32, values in ``[0, 1]``.
                * A :class:`numpy.ndarray` with the same format.

                For INT8 quantization, provide 20–100 representative images from your training/validation set for best
                accuracy.
            max_images: Maximum number of images to load from a calibration directory.  Defaults to ``100``.  Only used
                when *calibration_data* is a directory path.
            notes: Optional user-defined metadata (string, dict, list, or
                any JSON-serialisable value) to embed in the exported ONNX model under the ``"rfdetr_notes"`` metadata
                property.  When ``None`` no metadata entry is written.  String values are stored verbatim; all other
                types are JSON-encoded so consumers must call ``json.loads()`` to recover a dict or list.  The same
                value can be passed to :meth:`train` so the checkpoint and the ONNX file share the same provenance
                information.

        Returns:
            Path to the exported model file (``.onnx`` or ``.tflite``).
        zExporting model to ONNX format)onnxtflitezUnsupported export format z. Choose from: r   )export_onnxmake_infer_imagezlIt seems some dependencies for ONNX export are missing. Please run `pip install rfdetr[onnx]` and try again.r   FNzRFDETR.export() is not available after inplace optimization. The original model has been cleared. Create a new RFDETR instance.r   Tr   r  r_   r   z,num_windows must be a positive integer, got Model's default resolution (!) is not divisible by block_size=rR   rS   *). Provide an explicit shape divisible by rO   )r   inputfeatures)detslabelsmasks)r  r  	keypointsr  r  batchz PyTorch inference output shape: 
pred_boxespred_logits
pred_masksz)PyTorch inference output shapes - Boxes: z
, Labels: z	, Masks: pred_keypointsz, Keypoints: size)rS  rn   input_namesinput_tensorsoutput_namesdynamic_axesbackbone_onlyverboseopset_versionvariant_namer  z%Successfully exported ONNX model to: r  zTFLite export is experimental and work-in-progress. Upstream dependency instabilities (onnx2tf, ai_edge_litert) may affect results.r   r  )export_tflitezuIt seems some dependencies for TFLite export are missing. Please run `pip install rfdetr[onnx,tflite]` and try again.r   rg  )	onnx_pathrS  quantizationcalibration_data	verbosity
max_imagesr  z'Successfully exported TFLite model to: zExport completed successfully)(r   r   rU   rfdetr.export.mainr  r  r   rg  rn   rm   re   r  rt   r   r   r   r
   rj   rg   rV   rW   rf   r+  rb   r   segmentation_headuse_grouppose_keypointsr  rr   no_gradr   r\   r   r   rq   r  r  r   rfdetr.export._tflite.converterr  )%r|   rS  	infer_dirr  r  r  r\   rH  dynamic_batchr^   r   r  r  r  r  _valid_formatsr  r  rm   rn   output_dir_pathr_   r]   r  r  r  r   r  r  outputsr  r  r  r  output_filer  tflite_paths%                                        r=   r  zRFDETR.export\  s   L 	45+'9&?SaRbcdd	H ""4-u59I9I9QU   ::++..u5

))*v	;KK
T2":.O,Z9J9JHUJ!$"3"3]AFK+t,J{C4PT_cdTd #OP[!_``#k1J}..

0E0EF8j(A-$6tzz7L7L6M N&&0\zl/ZeYf gBBLQP  -UJ
KX,5*f4CTCTCaCabj  #)K *|""44:""::> &1?J\?YZtq'l 2ZZ#JJL s $]3HLL#CHNNCS!TU&&88#M2G"<0D$]3F#L1E!%6G

|S]^d^j^j]k l&&+kk]4
 'PQUQ[Q[P\\fgmgsgsft%uv&&>>#M2G"<0D$]3F '(8 9ILLCDJJ<zZ`ZfZfYg h&&/oo%68
 $M2G"<0D$]3FLL#LTZZLXbcicocobp!qr;s> IIK)--/M%/'+))++$T648K KK?}MN!f 	M ,)"?3!-%5(/fW)# Ek]ST"
  $zz//226:DJJ KK78$#zz//226:DJJW  	LLH 	l  [s sv # LLW ,  $zz//226:DJJsb   U) E:W V%)W FVBW %V +5W W ) V	W VW  V>>W 6W7c                6   t        |       rt        j                  j                  | dd      }t	        |d      5 }t        j                  |      }ddd       t        d   d       }h d	t        fd
|D              }|s|D cg c]  }|d   	 c}S |D ch c](  }|j                  dd      vs|j                  d      * }}|D ch c]  }|d   |v s|d    }}|D cg c]  }|d   |vs|d    }	}|	xs |D cg c]  }|d   	 c}S t        |       r.t        j                  t        j                  j                  | d            t        j                  t        j                  j                  | d            z   }
|
D cg c]3  }t        j                  j                  |      j                  d      s2|5 }}|d   }t	        |      5 }t        j                  |      }ddd       dv rHt!        |d   t"              r0t        |d   j%                               D cg c]
  }|d   |    c}S |d   S t'        d| d      t)        d|  d      # 1 sw Y   xY wc c}w c c}w c c}w c c}w c c}w c c}w # 1 sw Y   xY wc c}w )z7Load class names from a COCO or YOLO dataset directory.r6  _annotations.coco.jsonutf-8encodingN
categoriesc                8    | j                  dt        d            S )Nidinf)r   float)categorys    r=   <lambda>z&RFDETR._load_classes.<locals>.<lambda><  s    VZ\abg\hIi rk   )r  >   Nr   r   r   c              3  F   K   | ]  }|j                  d d      v  yw)supercategoryr   N)r   )r;   cplaceholderss     r=   r>   z'RFDETR._load_classes.<locals>.<genexpr>B  s"     dTUQUU?F;<Ods   !r   r  r   z*.yamlz*.ymldatar   nameszFound z' but it does not contain 'names' field.zCould not find class names in zX. Checked for COCO (train/_annotations.coco.json) and YOLO (data.yaml, data.yml) styles.)r   r   r   r   r]  r^  r   sortedrD  r   r   globr   r   yaml	safe_loadrV   r   keysrU   FileNotFoundError)r0  	coco_pathrv  annsr  
has_any_scr  parentshas_childrenr<  
yaml_pathsypyaml_data_files	yaml_pathr  ir  s                   @r=   _load_classeszRFDETR._load_classes5  sw    !-[';STIi'2 $ayy|$\ 28ijJ 6L dYcddJ+56a&	66
 8Bx!QUU?\bEckwEwquu_-xGx/9R!QvY'=QAfIRLR.8ZAfI\<Y1V9ZKZAj"A1V9"AA !-277<<X#FG$))TVT[T[T`T`alnuTvJwwJ,6bb"'':J:J2:N:Y:YZ`:arbOb'*Ii )A~~a()$d7mT26<T']=O=O=Q6RSDM!,SSG}$vi[0WXYY,[M :f f
 	
G$ $ 7
 yRZ"A c) ) TsY   I	I,I16I1I6I6)I;6I;J 3JJJ
*JI)
Jr  c                  t        |       rt        j                  j                  | dd      }|rt	        t        |      j                        S t        |d      5 }t        j                  |      }ddd       d   }|D ci c]  }|d   |
 }}t	        |      S t	        t        j                  |             S # 1 sw Y   JxY wc c}w )ae  Detect the class count using the same category basis as training labels.

        For COCO-style datasets this counts all categories by ``id`` from ``train/_annotations.coco.json`` (matching the
        remapping based on ``coco.cats`` used by the training datamodule). In keypoint mode it instead counts the
        inferred RF-DETR keypoint label slots. In legacy background-first schemas (e.g. ``[0, 17]``) slot ``0`` is
        reserved for classes without keypoints; active-first schemas (e.g. ``[17]``) use normal 0-based indices. For
        YOLO-style datasets it falls back to ``_load_classes``.
        r6  r  r  r  Nr  r  )r   r   r   r   r   r   r<  r]  r^  r   r8   r  )r0  r  r  rv  r  r  r  	cat_by_ids           r=    _detect_num_classes_for_trainingz'RFDETR._detect_num_classes_for_trainingb  s     !-[';STI&5i@LLMMi'2 $ayy|$l+JBLMh$1MIMy>!6''455$ $ Ns   B9C9Cc                   	 t         j                  || j                  j                        }g }| j                  j                  r;t        t        | j                  dg       xs g       }|rt        |t        |            }| j                  j                  }||k(  rydt        | j                  dt                     v }|st        j                  d||||       || j                  _        t        | j                   dd      }|||_        |r@t        |      |k  r1|d	g|t        |      z
  z  z   }|| j                  _        |||_        yyyyt        j%                  d
|||||       |rWt        |      |k  rH|d	g|t        |      z
  z  z   }|| j                  _        t        | j                   dd      }|||_        yyyy# t        t
        t        t        f$ r!}t        j                  d||       Y d}~yd}~ww xY w)u[  Auto-detect the dataset class count and align ``model_config.num_classes`` in-place.

        Must be called before ``RFDETRModelModule`` is constructed so that weight loading inside the module uses the
        correct (dataset-derived) class count.

        When the user did **not** explicitly set ``num_classes`` (it is left unset, e.g. inferred from a
        checkpoint), ``model_config.num_classes`` and ``self.model.args.num_classes`` are updated to match the dataset.
        When the user *did* set ``num_classes`` explicitly — to any value, including the class default — and it differs
        from the dataset, the configured value is preserved and a warning is emitted.

        Failures from ``_detect_num_classes_for_training`` are caught and logged at DEBUG level so that training is
        never blocked by detection errors.

        When ``model_config.use_grouppose_keypoints`` is True and
        ``model_config.num_keypoints_per_class`` is shorter than the adjusted
        ``num_classes``, the schema is zero-padded in-place so that
        ``len(num_keypoints_per_class) == num_classes``.  Both ``model_config``
        and ``model.args`` (if present) are updated.  Appended classes receive
        zero keypoints and contribute no class-logit boost.

        Args:
            dataset_dir: Path to the training dataset root directory.
        r  z7Could not auto-detect num_classes from dataset '%s': %sNr   r   r   zTDetected %d classes in dataset '%s'; auto-adjusting model num_classes from %d to %d.r}   r   zDataset '%s' has %d classes but model was initialized with num_classes=%d. Using the model's configured value (%d). If this is unintentional, reinitialize the model with num_classes=%d.)r8   r  rg   r  r  rU   KeyErrorr`  r   r   r   re   maxr   r   r   rn   r   rX  )	r|   r0  dataset_num_classesr"  keypoint_schemamodel_num_classesuser_overroderk  padded_schemas	            r=   rN  z&RFDETR._align_num_classes_from_datasetx  s"   0	"("I"I(,(9(9(Q(Q #J # &(44"74+<+<>WY[#\#b`bcO&)*=s??S&T# --99"33 &1B1BDVX[X])^^LLf#!# -@D) VT:J%)<
&
 3#7:M#M /1#9LsSbOc9c2d d<I!!9)9FJ6 * $N NN> #!!#	 3#7:K#K /1#9JSQ`Ma9a2b b<I!!9$TZZ>
)9FJ6 *	 $L{ ":xA 	LLRT_ade	s   +G   G:G55G:c                d    t        |       syt        |       dz  dz  }|j                         r|S dS )a  Return the Roboflow COCO train annotation path when it exists.

        Args:
            dataset_dir: Path to the Roboflow dataset root.

        Returns:
            Train split annotation path, or ``None`` when the dataset is not Roboflow COCO style.

        Raises:
            This helper does not raise.

        Example:
            >>> RFDETR._roboflow_keypoint_annotation_path("/missing") is None
            True
        Nr6  r  )r   r
   existsr0  annotation_paths     r=   "_roboflow_keypoint_annotation_pathz)RFDETR._roboflow_keypoint_annotation_path  s:    " %[1{+g58PP"1"8"8":DDrk   c                L    t        |       dz  dz  }|j                         r|S dS )a  Return the native COCO train keypoint annotation path when it exists.

        Args:
            dataset_dir: Path to the COCO dataset root.

        Returns:
            Path to ``annotations/person_keypoints_train2017.json``, or ``None`` when it is absent.

        Raises:
            This helper does not raise.

        Example:
            >>> RFDETR._coco_keypoint_annotation_path("/missing") is None
            True
        r   zperson_keypoints_train2017.jsonN)r
   r  r  s     r=   _coco_keypoint_annotation_pathz%RFDETR._coco_keypoint_annotation_path  s/    " {+m;>__"1"8"8":DDrk   c                b    t        |       }t        D ]  }||z  }|j                         s|c S  y)a  Return the YOLO data file path when a dataset root has one.

        Args:
            dataset_dir: Path to the YOLO dataset root.

        Returns:
            Path to ``data.yaml`` or ``data.yml``, or ``None`` when neither exists.

        Raises:
            This helper does not raise.

        Example:
            >>> RFDETR._yolo_data_file_path("/missing") is None
            True
        N)r
   r   r  )r0  rootfilename	data_files       r=   _yolo_data_file_pathzRFDETR._yolo_data_file_path  s=    " K 0 	!HxI!  	! rk   c                    g }t               }t        |       D ]b  \  }}||v s	||v s||k(  r|j                  |       %|t        |       k  s4| |   |k(  s=|j	                  ||g       |j                  ||h       d |S )zIConvert Ultralytics ``flip_idx`` permutation metadata to flat swap pairs.)r   	enumerater   r   extendr   )flip_idxpairsseenidx
mirror_idxs        r=   _flip_idx_to_pairszRFDETR._flip_idx_to_pairs  s     (2 	/OCd{jD0C:4ECM)hz.Bc.Ic:./S*-.	/ rk   c           	     N   | j                   j                  syt        |dd      }|dvryt        |dd      }|syt        | d      si | _        ||f}|| j                  v r| j                  |   \  }}}n	 |dk(  r(t
        j                  |      }|y|}d}t        |      }n{|dk(  rOt
        j                  |      }||}d	}t        |      }nOt
        j                  |      }	|	y|	}d
}t        |	      }n't
        j                  |      }	|	y|	}d
}t        |	      }|||f| j                  |<   |j"                  }t        |dg       st%        |j&                        |_        t%        t        | j                   dg       xs g       }dt        | j                   dt)                     v }|rt+        |      t+        |      k(  ry||k7  r|rt        j-                  d|||       nVt/        |      r3|r1t/        |      s&t1        j2                  d|d|d|dt4        d       t        j!                  d|||       || j                   _        t        | j6                  dd      }|||_        yyy# t        t        t        t        f$ r!}
t        j!                  d||
       Y d}
~
yd}
~
ww xY w)a~  Infer or validate keypoint schema from COCO, Roboflow COCO, or YOLO pose metadata.

        Args:
            config: Training configuration containing dataset location and format.

        Returns:
            ``None``. The model config is updated in-place when dataset metadata is available.

        Raises:
            This method does not raise for missing or malformed metadata; later dataset construction still validates
            keypoint-mode requirements.

        Example:
            >>> from rfdetr.config import RFDETRKeypointPreviewConfig, TrainConfig
            >>> model = object.__new__(RFDETR)
            >>> model.model_config = RFDETRKeypointPreviewConfig(pretrain_weights=None)
            >>> model.model = type("Context", (), {"args": None})()
            >>> model._align_keypoint_schema_from_dataset(TrainConfig(dataset_dir="/missing", tensorboard=False))
        Ndataset_file)cocoroboflowyolor0  _keypoint_schema_cacher  COCOr  zRoboflow COCOz	YOLO posez5Could not infer keypoint schema from dataset '%s': %skeypoint_flip_pairsr   r   zConfigured num_keypoints_per_class=%s does not match dataset keypoint metadata %s from '%s'. Using dataset metadata as the source of truth.zYLoaded checkpoint uses a legacy background-first keypoint schema num_keypoints_per_class=z&, but the dataset infers active-first z}. Training will shift person from slot 1 to slot 0; checkpoint head weights are now misaligned. Pass num_keypoints_per_class=z& to train() to keep the legacy schema.r   r  zFInferred num_keypoints_per_class=%s from %s keypoint metadata at '%s'.r}   )rg   r  re   rp   r  r8   r  r   r  r  r   r  rU   r  r`  r   r   r   r   r  r   r   rX  r    r  r  r   rn   )r|   rl  r   r0  	cache_keyinferredsource_pathsource_kindr  yolo_data_filer"  inferred_schemacurrent_schemauser_set_schemark  s                  r=   rM  z*RFDETR._align_keypoint_schema_from_dataset)  s   *   88v~t<;;fmT:t5602D'!;/	333151L1LY1W.Hk;6)&,&K&KK&XO&."1K"(K9/JH!Z/&,&O&OP[&\O&2&5&5#=o#N)/)D)D[)Q)1"&4&1#=n#M%+%@%@%MN%-"0K"-K9.IH 7?[5YD''	2"::v4b9)-h.J.J)KF&gd&7&79RTVW][]^3wt?P?PRdfifk7ll5nEI_`oIpp_,E"# '~6?SfgvSwMM33A2D E((7': ;88F7I J)	* $#$	 \#	 9HD5 VT:J%5D
2 &; - &z8WE SU`befs+   4I* AI* %'I* I* *J$JJ$c                &     | j                   di |S )zERetrieve the configuration parameters that will be used for training.r   )r   r   s     r=   rG  zRFDETR.get_train_config  r   rk   c                    t        |      S )a  Retrieve a model context from the provided architecture configuration.

        Args:
            config: Architecture configuration.

        Returns:
            ModelContext with model, postprocess, device, resolution, args, and class_names attributes.
        )r   )r|   rl  s     r=   r   zRFDETR.get_model  s     $F++rk   c                    t        | j                  d      r5| j                  j                  t        | j                  j                        S t        t              S )zRetrieve the class names supported by the loaded model.

        Returns:
            A list of class name strings, 0-indexed.  When no custom class names are embedded in the checkpoint, returns
            the standard 80 COCO class names.
        r<  )rp   rn   r<  r   r   r  s    r=   r<  zRFDETR.class_names  sB     4::}-$**2H2H2T

..//$%%rk   c                    | j                   ry| j                  st        j                  d       d| _        | j                  j                  j                          y)u  Put the underlying module in eval mode before unoptimized inference.

        Inference must never run with dropout / batch-norm in training mode. The warning that the model is not optimized
        is emitted at most once, but eval mode is (re)asserted on every call: ``train()`` reassigns ``self.model.model``
        to a module that PyTorch Lightning leaves in training mode (see ``train()``), so gating ``eval()`` behind the
        once-only warning would let a later ``predict()`` silently run with dropout active.

        When ``_is_optimized_for_inference`` is ``True``, the method returns immediately — the compiled
        ``inference_model`` snapshot is already in eval mode and ``self.model.model`` is not used for inference.
        NzModel is not optimized for inference. Latency may be higher than expected. For full GPU throughput (e.g. ~8x on T4 via FP16 Tensor Cores), call model.optimize_for_inference(dtype=torch.float16).T)r   r   r   rX  rn   r  r  s    r=   +_ensure_eval_mode_for_unoptimized_inferencez2RFDETR._ensure_eval_mode_for_unoptimized_inference  sM     ++GGNNK
 HLDD

rk   c                
   ddl m}m} t        || j                  d      }t        | j                  dd      }	t        |	t              st        |	t              r|	dk  rt        d|	      ||	z  }
|9| j                  j                  }||
z  dk7  r)t        d| d	|
 d
| d|	 d|
 d      t        ||
||	      }| j                          t        |t              s|g}g }g }|rg nd}|D ]W  }t        |t              rG|j!                  d      r!t#        j$                  |d      j&                  }t)        j*                  |      }t        |t,        j.                        s|rut1        j2                  |      }|j4                  t0        j6                  k7  r2|dz  j9                  dd      j;                  t0        j6                        }|j=                  |       t?        j@                  |      }n`|r^|j=                  |jC                  ddd      jE                         jG                         dz  j;                  t0        j6                               |dkD  jI                         rt        d      |dk  jI                         rt        d      |jJ                  d   | j                  jL                  k7  r9t        d| j                  jL                   dtO        |jJ                         d      |}|jJ                  dd \  }}|j=                  ||f       |j=                  |jQ                  | j                  jR                               Z |t        |      n+| j                  j                  | j                  j                  g}t-        jT                  |D cg c]  }t?        jV                  ||       c}      }t?        jX                  || jZ                  | j\                        }| j^                  r| j`                  |jJ                  d   k7  s| j`                  |jJ                  d   k7  rZt        | dd      rdnd}t        d| j`                   d| j`                   d|jJ                  d    d|jJ                  d    d	|z         | jb                  rY| jd                  |jJ                  d   k7  r=t        | dd      rdnd }t        d!| jd                   d|jJ                  d    d|z         | j^                  r6| j                  jg                  |jQ                  | jh                  "            }n| j                  j                  |      }t        |tN              rN|d   |d   d#}tk        |      dk(  r3t        t        | j                  d$d      d%d      r	|d   |d&<   n|d   |d'<   |}t-        jl                  || j                  jR                  (      }| j                  jo                  ||)      }| jp                  }tk        |      }t        | j                  d*d      }|'|t        tr              k(  rtt        jw                  d+       t        |d,|      }||kD  xr |t        tr              k(  } t        |d-g       xs g }!ty        |!      }"| r,t{        t|              D #$ci c]  \  }#}$|#|k  s|$||#    }%}#}$na|"rKt{        |!      D &'cg c]  \  }&}'|'dkD  s|& }(}&}'t{        |(      D #)ci c]  \  }#})|#|k  s|)||#    }%}#})nt        t{        |            }%g }*t{        |      D ])  \  }#}+|+d.   },|+d/   }-|+d0   }.|,|kD  }/|,|/   },|-|/   }-|.|/   }.d}0d1|+v r4|+d1   |/   }1|1j                         jE                         jG                         }0|0du}2d2|+v r|+d2   }3|3|/   }3 ||.j                         jE                         jG                         |,j                         jE                         jG                         |-jE                         jG                         |3j                  d      jE                         jG                         3      }4n{ ||.j                         jE                         jG                         |,j                         jE                         jG                         |-jE                         jG                         4      }4d5|+v rA|+d5   |/   }5|5j                         jE                         jG                         |4j                  d5<   |r||#   |4j                  d6<   t1        j                  t1        j2                  ||#   t0        j                  "      tk        |4      df      |4j                  d7<   |4j                  |4j                  nt1        j2                  g t        "      }6|"rdn|}7|6D 8cg c]  }8|8|%vs|8|7k7  s|8 }9}8|9rtt        jw                  d8|9dd9        | r |6D 8cg c]  }8|%j%                  |8d:       }:}8n&|6D 8cg c]  }8|8|7k(  rd;n|%j%                  |8d:       }:}8t1        j2                  |:t        "      |4j                  d<<   |2r|0t        |4j                        };|4j                  j;                  t0        j                        |;d=<   |r(t        tk        |4            D <cg c]  }<||#   	 c}<|;d6<   |;j%                  d5      }=|;j%                  d7      }>|=|>tk        |4      dkD  rt1        j                  |=t0        j                  "      }?t1        j                  |>t0        j                  "      }@|?jJ                  dd |0jJ                  dd k(  r*@jJ                  tk        |4      dfk(  rt        |?@>      |;d?<   |0j;                  t0        j                  d@      }0|0dddddf   }A ||0ddddddf   |A|4j                  )|4j                  j;                  t0        j                        nd|4j                  |4j                  j;                  t              ndAdkD  |;A      }B|*j=                  |B       |*j=                  |4       , tk        |*      dkD  r|*S |*d   S c c}w c c}$}#w c c}'}&w c c})}#w c c}8w c c}8w c c}8w c c}<w )Bu"  Performs model inference on the input images.

        This method accepts a single image or a list of images in various formats (file path, image url, PIL Image,
        NumPy array, or torch.Tensor). The images should be in RGB channel order. If a torch.Tensor is provided, it must
        already be normalized to values in the [0, 1] range and have the shape (C, H, W).

        Args:
            images:
                A single image or a list of images to process. Images can be provided
                as file paths, PIL Images, NumPy arrays, or torch.Tensors.
            threshold:
                The minimum confidence score needed to consider a detected bounding box valid.
            shape:
                Optional ``(height, width)`` tuple to resize images to before inference. When provided, overrides the
                model's default inference resolution. The tuple should match the resolution used when exporting the
                model (typically a square shape). Both dimensions must be positive integers divisible by ``patch_size *
                num_windows``. Defaults to ``(model.resolution, model.resolution)`` when not set.
            patch_size:
                Backbone patch size used for shape divisibility validation. Defaults to ``model_config.patch_size``
                (typically 14 for large models, 16 for smaller ones). Divisibility is checked against ``patch_size *
                num_windows``.
            include_source_image:
                Whether to attach the original image to the returned prediction. Detection and segmentation outputs use
                ``detections.metadata["source_image"]``. Keypoint outputs use per-object
                ``key_points.data["source_image"]`` because Supervision ``KeyPoints`` currently has no collection-level
                metadata field. Defaults to ``True``. Set to ``False`` to reduce memory use when source images are not
                needed.
            **kwargs:
                Additional keyword arguments.

        Returns:
            A single or multiple Supervision prediction objects. Detection and segmentation models return
            :class:`~supervision.Detections`. Keypoint models return :class:`~supervision.KeyPoints`, with keypoint
            coordinates in ``xy``. Keypoint predictions preserve the detection-level fields produced by RF-DETR:
            ``key_points.detection_confidence`` is the per-object score used by ``threshold``. For keypoint models this
            is the postprocessed detection score and, by default, includes keypoint uncertainty fusion controlled by
            ``model_config.postprocess_trace_alpha``. ``key_points.keypoint_confidence`` is separate: it is a
            ``(num_detections, num_keypoints)`` array of per-keypoint findability scores decoded from the keypoint head,
            not a repeated copy of the detection score. When RF-DETR emits keypoint precision parameters,
            ``key_points.data["covariance"]`` stores per-keypoint pixel-space covariance matrices with shape
            ``(num_detections, num_keypoints, 2, 2)``. ``key_points.data["xyxy"]`` stores the corresponding detection
            boxes as a ``(num_detections, 4)`` array in the same row order as ``key_points.xy`` because Supervision
            ``KeyPoints`` does not have a native bounding-box field. The ``data`` dict also contains ``class_name`` and
            ``source_shape`` as per-object arrays. When ``include_source_image=True`` for keypoint models,
            ``source_image`` is stored as per-object data until Supervision exposes collection-level metadata for
            ``KeyPoints``.

        Note:
            For ``Detections`` outputs, ``source_image`` moved from ``detections.data`` to ``detections.metadata``.
            Update detection callers reading ``detections.data["source_image"]`` to use
            ``detections.metadata["source_image"]``.

        Note:
            ``class_name`` mapping uses one of three modes depending on the checkpoint. For pretrained COCO checkpoints
            (detected when ``model.args.num_classes > len(class_names)`` and ``class_names`` matches
            ``COCO_CLASS_NAMES``), raw COCO category IDs (1–90, sparse) are looked up by category ID rather than by
            position — so ``class_id=18`` yields ``"dog"``, not ``class_names[18]``. For fine-tuned detection and
            segmentation models and active-first keypoint models, ``class_id`` is a 0-based index into ``class_names``.
            Legacy keypoint checkpoints with ``args.num_keypoints_per_class[0] == 0`` use a background-first layout:
            slot 0 maps to ``"__background__"`` and foreground slots map to ``class_names`` in order.

        Raises:
            ValueError: If ``shape`` cannot be unpacked as a two-element sequence,
                if either dimension does not support the ``__index__`` protocol (e.g. ``float``) or is a ``bool``, if
                either dimension is zero or negative, if either dimension is not divisible by ``patch_size *
                num_windows``, or if ``patch_size`` is not a positive integer.
        r   r#   predictr_   r   z9model_config.num_windows must be a positive integer, got Nr  r  rR   rS   r  rO   httpT)stream   r   zYImage has pixel values above 1. Please ensure the image is normalized (scaled to [0, 1]).zYImage has pixel values below 0. Please ensure the image is normalized (scaled to [0, 1]).z~Invalid tensor image shape. Tensor inputs to `predict()` must be in (C, H, W) format with C matching the model configuration (z' channels). Received tensor with shape r   r   Fz< Create a new RFDETR instance to use a different resolution.zY You can explicitly remove the optimized model by calling model.remove_optimized_model().z8Resolution mismatch. Model was optimized for resolution xz
, but got zF Create a new RFDETR instance to recompile for a different batch size.z You can explicitly remove the optimized model by calling model.remove_optimized_model(). Alternatively, you can recompile the optimized model for a different batch size by calling model.optimize_for_inference(batch_size=<new_batch_size>).zABatch size mismatch. Optimized model was compiled for batch size ry  )r  r  rg   r  r  r  )rm   )target_sizesr}   u   predict(): model has no 'args' attribute — COCO sparse-ID mapping cannot activate; class_ids are treated as 0-indexed (may be wrong for pretrained COCO checkpoints)r   r   scoresr  boxesr  r  )xyxy
confidenceclass_idmask)r  r  r  keypoint_precision_choleskysource_imagesource_shapeuJ   predict() encountered unmapped class_id(s): %s — mapping to empty string   r   __background__
class_namer  )precision_choleskyr#  
covariance)r   )xykeypoint_confidencedetection_confidencer  visibler  )Nsupervisionr$   r%   rj   rg   re   rV   rW   rf   rU   rn   r+  rb   r  r   rq   r   requestsr   rawr   r]  rr   r   nparrayrz  uint8clipastypeappendF	to_tensorpermuter   numpyrD  r\   r   tuplert   rm   stackresize	normalizer   r   r   r   r   r   r   r   r   tensorpostprocessr<  r   r   warning_oncer    r  r   r   r  squeezer  metadatatileint64r  objectr  float32r   asarrayr!   r  )Cr|   images	thresholdr\   r^   include_source_imager~   r$   r%   r_   r]   default_res
orig_sizesprocessed_imagessource_imagesimgsrc
img_tensorhr>  	resize_totbatch_tensor_restore_hintpredictionsreturn_predictionsr  resultsmodel_class_namesr  _model_argsnum_logit_slots_is_coco_pretrained_num_keypoints_per_class_is_legacy_bgfirst_keypointr  coco_id_class_id_to_namer  r	  _kp_foreground_slotsslotpredictions_listresultr  r  r  keepkeypoints_arrayr  has_keypointsr  
detectionskeypoint_precision	class_ids_bg_sentinelcid	truly_oobr<  keypoint_datar   raw_precisionraw_source_shape	precisionr#  r*  
key_pointssC                                                                      r=   r  zRFDETR.predict  s   \ 	6(T5F5F	R
d//Bk4(
;0LP[_`P`XYdXghii+-
=**//KZ'1, 2;- @"",]:,oVaUb c>>H\L  )
JTE88:&$'XF
2 #	FC#s#>>&)",,s48<<Cjjoc5<<0'((3-CyyBHH,"Sy..q#6==bhhG!((-kk#&%$$ckk!Q&:&>&>&@&F&F&H3&N%V%VWYW_W_%`aa}} o  a}} o  yy|t00=== @@D@Q@Q@^@^?_ `227		2B1C1F 
 J##AB'DAqq!f%##JMM$**2C2C$DEG#	FJ $)#4DK4::;P;PRVR\R\RgRg:h	{{DT#UqAHHQ	$:#UV{{<TYYG++**l.@.@.CC--1C1CA1FF t%95A St 
 !::>:T:T9UUVW[WqWqVr s+11!45Q|7I7I!7L6MQPR_` 
 00--1C1CA1FF #4)=uE ae	 " %GGKGaGaFb c##/#5#5a#8"9<>KL  ++**44\__4K`K`_5abK****<8Kk5)*1~)!n" ;1$74::~tDF_afg;Fq>&'787B1~&|4,K||Jtzz7H7HI**((<(P ,,!" djj&$7#4=M8N#Nd  '{M1E-1a6G4P`Ka6a /6kC\^`.a.geg &9:R&S#@I,@W12<!W[\_`[`*1--1 1 ) 7@@X6Y#cFC]^ab]bC#c #cKTUiKj t4norsns'8';!; t t $Y/@%A B9;"7+ ^	4IAvH%FH%F7OEI%DD\FD\F$KE"Of$";/5	"+//"3"7"7"9"?"?"A+47M& wd'**,224%||~11399;#ZZ\//1q)--/557	
 (**,224%||~11399;#ZZ\//1

 -6%+,I%J4%P"ASAYAYA[A_A_AaAgAgAi
 =>#6CA6F
##N3.0ggbhhz!}TVT\T\6]`cdn`oqr_s.tJOON+ 0:/B/B/N
++TVT\T\]_gjTkI !<1L(1jS@Q5QVY]iVijIj##`bqM #IRS#044S"=SS ludg|(;$ARAVAVWZ\^A__  -/HH[,OJOOL)!< $Z__ 5(2(>(>rzz(Jf%'OTUXYcUdOe4f!]15E4fM.1 - 1 12O P#0#4#4^#D  ,1A1MRUV`RadeRe "

=

 KI#%::.>bjj#QL r*o.C.CBQ.GGLL^L^cfgqcrtubvLv6\/8|7l3 #2"8"8%"8"P&5aAg&>#&&q!RaRx0(;!,,8 *4)>)>)E)Ebjj)Q@J@S@S@_Z0077<ei/!3&	
 !''
3 ''
3}^	4@ $''7#81#<UBRSTBUUy $VZ1 $d tp k T 5gsN   qqq:q%q%q++q+	q1%q1+q1q62 q;r c                   ddl m} |"t        j                  d      }|t	        d       ||      }|j                  |      }| j                  |t	        d      | j                  xs |}t        j                  d	      5 }| j                  |       |j                  |      }	|	j                  |      }
|
j                  ||d
       ddd       y# 1 sw Y   yxY w)a  Deploy the trained RF-DETR model to Roboflow.

        Deploying with Roboflow will create a Serverless API to which you can make requests.

        You can also download weights into a Roboflow Inference deployment for use in Roboflow Workflows and on-device
        deployment.

        Args:
            workspace: The name of the Roboflow workspace to deploy to.
            project_id: The project ID to which the model will be deployed.
            version: The project version to which the model will be deployed.
            api_key: Your Roboflow API key. If not provided,
                it will be read from the environment variable `ROBOFLOW_API_KEY`.
            size: The size of the model to deploy. If not provided,
                it will default to the size of the model being trained (e.g., "rfdetr-base", "rfdetr-large", etc.).

        Raises:
            ValueError: If the `api_key` is not provided and not found in the
                environment variable `ROBOFLOW_API_KEY`, or if the `size` is not set for custom architectures.

        Note:
            Bundle creation is delegated to :meth:`export_for_roboflow`, which can be called independently
            to write ``weights.pt`` and ``class_names.txt`` without a network round-trip.
        r   )RoboflowNROBOFLOW_API_KEYzHSet api_key=<KEY> in deploy_to_roboflow or export ROBOFLOW_API_KEY=<KEY>)api_keyz&Must set size for custom architecturesroboflow_upload_)prefix
weights.pt)
model_type
model_pathr  )r  ru  r   getenvrU   	workspacer  tempfileTemporaryDirectoryexport_for_roboflowprojectversiondeploy)r|   r~  
project_idr  rw  r  ru  rftmp_out_dirr  project_versions              r=   deploy_to_roboflowzRFDETR.deploy_to_roboflow  s    @ 	&?ii 23G !kllg&LL+	99EFFyy D((0BC 	c{$$[1''
3G%oog6O""d{Ua"b		c 	c 	cs   ACCc                T   t        j                  |d       t         j                  j                  |d      }t	        |ddd      5 }|j                  dj                  | j                               ddd       t        | j                  j                        }t        |d	      r|j                  | j                  |_        t         j                  j                  |d
      }t        j                  | j                  j                  j                         |d|       y# 1 sw Y   xY w)a  Write a Roboflow upload bundle (``weights.pt`` + ``class_names.txt``) into *output_dir*.

        This is the network-free core of :meth:`deploy_to_roboflow`: it serialises the model state and
        training args into ``weights.pt``, always embedding ``class_names`` into a copy of the args so
        the bundle is self-contained, and writes the class labels to ``class_names.txt``.  The Roboflow
        SDK uses this format to adapt raw PyTorch-Lightning checkpoints into a deploy-ready bundle.

        Args:
            output_dir: Directory into which ``weights.pt`` and ``class_names.txt`` are written.  Created
                if it does not exist.  Existing files are silently overwritten.

        Raises:
            PermissionError: If the process lacks write access to *output_dir* or its parent directory.
            OSError: On disk-full, invalid path, or other filesystem failure during directory creation,
                file write, or ``torch.save``.
        Tr   zclass_names.txtr>  r  
)r  newlineNr<  rz  )rn   r}   )r   r   r   r   r]  writer<  r   rn   r}   rp   rr   saver   )r|   rS  class_names_pathrv  r}   outpaths         r=   r  zRFDETR.export_for_roboflowM  s    " 	J. 77<<
4EF"C'4H 	1AGGDIId../0	1 DJJOO$t]+t/?/?/G#//D'',,z<8

TZZ--88:DI7S	1 	1s   +DD')r   r   )r   str | os.PathLike[str]r~   r   r   r8   )rm   r   r   z#tuple[str | None, list[int] | None])
r  rW   rH  rf   rz  ztorch.dtype | strrw  rW   r   None)r   r  )r   rW   )outputNF   TNr   FNr  NNd   )rS  rq   r  
str | Noner  rW   r  rf   r  rW   r\   tuple[int, int] | NonerH  rf   r  rW   r^   
int | Noner   rq   r  r  r  zstr | np.ndarray | Noner  rf   r  rE  r   r
   )r0  rq   r   	list[str])r0  rq   r  rW   r   rf   )r0  rq   r   r  )r0  rq   r   zPath | None)r  	list[int]r   r  )rl  r   r   r  )r   r   )rl  r   r   r   r   r  )g      ?NNT)rH  zcstr | Image.Image | np.ndarray | torch.Tensor | list[str | np.ndarray | Image.Image | torch.Tensor]rI  r  r\   r  r^   r  rJ  rW   r~   r   r   z5Detections | KeyPoints | list[Detections | KeyPoints]r  )r~  rq   r  rq   r  z	int | strrw  r  r  r  r   r  )rS  r  r   r  ),rY   
__module____qualname____doc__r   r   r  r   r   __annotations__r   r   r   r   r   classmethodr  staticmethodr#  r6  r   rr   rF  r  rZ  propertyr  r  r  r  rN  r  r  r  r  rM  rG  r   r<  r  inference_moder  r  r  r   rk   r=   r8   r8      sh   G "E DD-8*8-8*8(,F02 o ob	 $ $L^h@  #(==	_ __ _ !	_ _ 
_ _B7(r ': ':V # $#(,#!%#'48W;  !W;W; W; 	W;
 W; W; &W; W; W; W; W; !W; 2W; W;  !W;" 
#W;r *
 *
X ^c 6 6*_GB E E* E E&  .  nE`2	, 
& 
& , U (,!%%)JVsJV JV &	JV
 JV #JV JV 
?JV  JVb
 #2c2c 2c 	2c
 2c 2c 
2ch!Trk   c                    | t         v r0t        j                  d      }t        ||       }|t	               | <   |S t        dt        d|       )zFLazily resolve legacy re-exports without creating import-order cycles.zrfdetr.variantszmodule z has no attribute )_VARIANT_EXPORTS	importlibimport_modulere   globalsr{  rY   )r   rn  r  s      r=   __getattr__r  q  sQ    (():;%	$
78,.@I
JJrk   c                 Z    t        t        t                     t        t              z        S )z1Include lazy re-exports in interactive discovery.)r  r   r  r  r   rk   r=   __dir__r  |  s    #gi.3'7#8899rk   )
r\   rE  r]   rf   r^   rf   r_   rf   r   ztuple[int, int])r^   r  rg   rE  rh   rq   r   rf   )ru   r   r   r  )r   "Callable[Concatenate[Any, _P], _R]r   r  )r   rq   r  )Z
__future__r   r}  r  r  r^  rZ   r   r  r  collectionsr   collections.abcr   r   r   	functoolsr	   pathlibr
   typingr   r   r   r   r   r9  r0  r.  rr   !torchvision.transforms.functional
transforms
functionalr6  r  PILr   rfdetr.assets.coco_classesr   r   rfdetr.assets.model_weightsr   r   rfdetr.configr   r    rfdetr.datasets._keypoint_schemar   r   r   rfdetr.datasets.cocor   rfdetr.datasets.yolor   r   rfdetr.inferencer   r   rfdetr.utilities.distributedr   rfdetr.utilities.keypointsr    r!   rfdetr.utilities.loggerr"   r-  r$   r%   set_float32_matmul_precisionrW  r   r'   r(   r  __all__	frozensetr:   r:  r?   r  rB   rI   rM   rb   rj   ry   r   r8   r  r  r   rk   r=   <module>r     s   #      	   # $    F F    - -   E V 2 
 7 P ? 8 b .1	&E&&v. 
t_T] " ^
7&6
7*35Lk4Z*[ '8= >%5> 9 $o  >_ )? ^> :  C "$? ... . 	.
 .bD+*"LT LT^<K:UB  		s   E E%$E%