@@ -27,8 +27,13 @@ def task_of_model_type(model_type: str) -> str:
2727
2828 Non-detect tasks double as the model_type suffix token
2929 (e.g. 'yolov11-seg' -> TASK_SEG). Plain 'yolov11' / 'rfdetr-base' -> TASK_DET.
30+
31+ Keypoint/pose models may spell the token as either 'pose' (Ultralytics) or
32+ 'keypoint' (rf-detr, e.g. 'rfdetr-keypoint-preview'); both map to TASK_POSE.
3033 """
3134 s = model_type .lower ()
35+ if "keypoint" in s :
36+ return TASK_POSE
3237 for task in (TASK_SEM , TASK_SEG , TASK_POSE , TASK_CLS , TASK_OBB ):
3338 if task in s :
3439 return task
@@ -317,17 +322,22 @@ def _process_yolo(model_type: str, model_path: str, filename: str) -> tuple[str,
317322def _detect_rfdetr_task (checkpoint ) -> Optional [str ]:
318323 """Detect the training task of an rf-detr checkpoint.
319324
320- rf-detr currently only supports weight upload for detection and instance
321- segmentation. Modern checkpoints (rf-detr v1.7+) store the Python class
322- name at `checkpoint["model_name"]` (e.g. 'RFDETRNano' vs 'RFDETRSegNano');
323- older checkpoints — including those downloaded from Roboflow — lack that
324- field but always carry `args.segmentation_head: bool`.
325+ rf-detr supports weight upload for detection, instance segmentation, and
326+ keypoint detection. Modern checkpoints (rf-detr v1.7+) store the Python
327+ class name at `checkpoint["model_name"]` (e.g. 'RFDETRNano' vs
328+ 'RFDETRSegNano' vs 'RFDETRKeypointPreview'); older checkpoints — including
329+ those downloaded from Roboflow — lack that field but always carry
330+ `args.segmentation_head: bool`. Keypoint support is recent enough that those
331+ checkpoints always carry `model_name`, so no args fallback is needed for it.
325332 """
326333 if not isinstance (checkpoint , dict ):
327334 return None
328335 model_name = checkpoint .get ("model_name" )
329336 if isinstance (model_name , str ):
330- return TASK_SEG if TASK_SEG in model_name .lower () else TASK_DET
337+ name = model_name .lower ()
338+ if "keypoint" in name :
339+ return TASK_POSE
340+ return TASK_SEG if TASK_SEG in name else TASK_DET
331341 args = checkpoint .get ("args" )
332342 if args is None :
333343 return None
@@ -356,6 +366,8 @@ def _process_rfdetr(model_type: str, model_path: str, filename: str) -> tuple[st
356366 "rfdetr-seg-large" ,
357367 "rfdetr-seg-xlarge" ,
358368 "rfdetr-seg-2xlarge" ,
369+ # Keypoint detection models
370+ "rfdetr-keypoint-preview" ,
359371 ]
360372 if model_type not in _supported_types :
361373 raise ValueError (f"Model type { model_type } not supported. Supported types are { _supported_types } " )
0 commit comments