@@ -56,6 +56,9 @@ def _get_processor_function(model_type: str) -> Callable:
56
56
57
57
if "yolonas" in model_type :
58
58
return _process_yolonas
59
+
60
+ if "yolov12" in model_type :
61
+ return _process_yolov12
59
62
60
63
return _process_yolo
61
64
@@ -107,18 +110,6 @@ def _process_yolo(model_type: str, model_path: str, filename: str) -> str:
107
110
108
111
print_warn_for_wrong_dependencies_versions ([("ultralytics" , ">=" , "8.3.0" )], ask_to_continue = True )
109
112
110
- elif "yolov12" in model_type :
111
- try :
112
- import torch
113
- import ultralytics
114
- except ImportError :
115
- raise RuntimeError (
116
- "The ultralytics python package is required to deploy yolov12"
117
- " models. Please install it with `pip install ultralytics`"
118
- )
119
-
120
- print_warn_for_wrong_dependencies_versions ([("ultralytics" , ">=" , "8.3.78" )], ask_to_continue = True )
121
-
122
113
model = torch .load (os .path .join (model_path , filename ))
123
114
124
115
if isinstance (model ["model" ].names , list ):
@@ -130,13 +121,12 @@ def _process_yolo(model_type: str, model_path: str, filename: str) -> str:
130
121
class_names .sort (key = lambda x : x [0 ])
131
122
class_names = [x [1 ] for x in class_names ]
132
123
133
- if "yolov8" in model_type or "yolov10" in model_type or "yolov11" in model_type or "yolov12" in model_type :
124
+ if "yolov8" in model_type or "yolov10" in model_type or "yolov11" in model_type :
134
125
# try except for backwards compatibility with older versions of ultralytics
135
126
if (
136
127
"-cls" in model_type
137
128
or model_type .startswith ("yolov10" )
138
129
or model_type .startswith ("yolov11" )
139
- or model_type .startswith ("yolov12" )
140
130
):
141
131
nc = model ["model" ].yaml ["nc" ]
142
132
args = model ["train_args" ]
@@ -210,6 +200,63 @@ def _process_yolo(model_type: str, model_path: str, filename: str) -> str:
210
200
return zip_file_name
211
201
212
202
203
+ def _process_yolov12 (model_type : str , model_path : str , filename : str ) -> str :
204
+ # For YOLOv12, since it uses a special Ultralytics version,
205
+ # state dict extraction and model artifacts are handled during model conversion
206
+
207
+ print (
208
+ "Note: Model must be trained using ultralytics from https://github.com/sunsmarterjie/yolov12 "
209
+ "or through the Roboflow platform"
210
+ )
211
+
212
+ # Check if model_path exists
213
+ if not os .path .exists (model_path ):
214
+ raise FileNotFoundError (f"Model path { model_path } does not exist." )
215
+
216
+ # Find any .pt file in model path
217
+ model_files = os .listdir (model_path )
218
+ pt_file = next ((f for f in model_files if f .endswith ('.pt' )), None )
219
+
220
+ if pt_file is None :
221
+ raise RuntimeError ("No .pt model file found in the provided path" )
222
+
223
+ # Copy the .pt file to weights.pt if not already named weights.pt
224
+ if pt_file != "weights.pt" :
225
+ shutil .copy (
226
+ os .path .join (model_path , pt_file ),
227
+ os .path .join (model_path , "weights.pt" )
228
+ )
229
+
230
+ required_files = [
231
+ "weights.pt"
232
+ ]
233
+
234
+ optional_files = [
235
+ "results.csv" ,
236
+ "results.png" ,
237
+ "model_artifacts.json"
238
+ ]
239
+
240
+ zip_file_name = "roboflow_deploy.zip"
241
+ with zipfile .ZipFile (os .path .join (model_path , zip_file_name ), "w" ) as zipMe :
242
+ for file in required_files :
243
+ zipMe .write (
244
+ os .path .join (model_path , file ),
245
+ arcname = file ,
246
+ compress_type = zipfile .ZIP_DEFLATED
247
+ )
248
+
249
+ for file in optional_files :
250
+ if os .path .exists (os .path .join (model_path , file )):
251
+ zipMe .write (
252
+ os .path .join (model_path , file ),
253
+ arcname = file ,
254
+ compress_type = zipfile .ZIP_DEFLATED
255
+ )
256
+
257
+ return zip_file_name
258
+
259
+
213
260
def _process_huggingface (
214
261
model_type : str , model_path : str , filename : str = "fine-tuned-paligemma-3b-pt-224.f16.npz"
215
262
) -> str :
0 commit comments