2222from dashscope .finetune .finetunes import FineTunes
2323
2424from dashscope .finetune .reinforcement .common .errors import (
25- OSSUploadError , RegistrationError , ValidationError , IOErrorWithCode , RuntimeErrorWithCode , ValueErrorWithCode ,
25+ OSSUploadError , RegistrationError , ValidationError , IOErrorWithCode , RuntimeErrorWithCode , ValueErrorWithCode , DatasetsError
2626)
2727from dashscope .finetune .reinforcement import logger
2828from dashscope .finetune .reinforcement import DASHSCOPE_HTTP_BASE_URL
2929from dashscope .finetune .reinforcement import set_api_key , get_filepath_classname , generate_random_id , get_func_type_id , deep_remove_none
30- from dashscope .finetune .reinforcement import FunctionType , FileSpec , TrainingType , AgenticRLFunctionComponent , RolloutFunctionComponent , RewardFunctionComponent , Datasets
30+ from dashscope .finetune .reinforcement import FunctionType , DatasetsType , FileSpec , TrainingType , DataSourceType
31+ from dashscope .finetune .reinforcement import AgenticRLFunctionComponent , RolloutFunctionComponent , RewardFunctionComponent , Datasets , Dataset , TrainingDataset , ValidationDataset
3132from dashscope .finetune .reinforcement import AgenticRLTuning , TuningModel
3233from dashscope .finetune .reinforcement import RewardInput , RolloutInput , GroupRewardInput
3334
@@ -56,35 +57,57 @@ def _tuningmodel_from_cfg(self, cfg: Dict[str, Any]) -> TuningModel:
5657 workspace_dir = cfg .get ("workspace_dir" , "./" )
5758
5859 # classpaths & runtimes:
59- self .tuning .fcs = []
60+ self .tuning .functions = []
6061 functions = cfg .get ("functions" , [])
6162 functions = [functions ] if not isinstance (functions , List ) else functions
6263 for f in functions :
6364 type = f .get ("type" , None )
64- names = f .get ("names" , None )
65- weights = f .get ("weights" , None )
66- reward_metric_weights = f .get ("reward_metric_weights" , None )
67- classpaths = f .get ("classpaths" , None )
68- runtimes = f .get ("runtimes" , None )
65+ name = f .get ("name" , None )
66+ weight = f .get ("weight" , None )
67+ timeout = f .get ("timeout" , None )
68+ reward_metric_weight = f .get ("reward_metric_weight" , None )
69+ runtime = f .get ("runtime" , None )
70+ fcmodel = f .get ("fcmodel" , None )
71+
6972 self .tuning .add_function_components (
7073 type = FunctionType (type ) if type is not None else None ,
71- classpaths = classpaths ,
72- runtimes = runtimes ,
73- names = names ,
74- weights = weights ,
75- reward_metric_weights = reward_metric_weights ,
74+ classpaths = fcmodel .get ("classpath" , None ) if fcmodel else None ,
75+ entity_ids = fcmodel .get ("entity_id" , None ) if fcmodel else None ,
76+ runtimes = runtime ,
77+ names = name ,
78+ weights = weight ,
79+ timeouts = timeout ,
80+ reward_metric_weights = reward_metric_weight ,
7681 workspace_dir = workspace_dir )
7782
7883 ########################################################################################## Datasets
7984 # Sync dataset IDs to Datasets model
80- if "training_files" in cfg :
81- for path in cfg ["training_files" ]:
82- component = FileSpec (path = path )
83- self .tuning .datasets .training_files .append (component )
84- if "validation_files" in cfg :
85- for path in cfg ["validation_files" ]:
86- component = FileSpec (path = path )
87- self .tuning .datasets .validation_files .append (component )
85+ # if "training_files" in cfg:
86+ # for path in cfg["training_files"]:
87+ # component = FileSpec(path=path)
88+ # self.tuning.datasets.training_files.append(component)
89+ # if "validation_files" in cfg:
90+ # for path in cfg["validation_files"]:
91+ # component = FileSpec(path=path)
92+ # self.tuning.datasets.validation_files.append(component)
93+ if "datasets" in cfg :
94+ for ds in cfg ["datasets" ]:
95+ type = ds .get ("type" , None )
96+ data_source_type = ds .get ("data_source_type" , None )
97+ file_name = ds .get ("file_name" , None )
98+ file_id = ds .get ("file_id" , None )
99+ download_url = ds .get ("download_url" , None )
100+ mount_storage = ds .get ("mount_storage" , None )
101+
102+ dataset = Dataset (
103+ type = DatasetsType (type ) if type else DatasetsType .TRAINING ,
104+ data_source_type = DataSourceType (data_source_type ) if data_source_type else DataSourceType .FILE_ID ,
105+ file_name = file_name if data_source_type == DataSourceType .FILE_ID else None ,
106+ file_id = file_id if data_source_type == DataSourceType .FILE_ID else None ,
107+ download_url = download_url if data_source_type == DataSourceType .DOWNLOAD_URL else None ,
108+ mount_storage = mount_storage if data_source_type == DataSourceType .OSS_MOUNT else None
109+ )
110+ self .tuning .datasets .append (dataset )
88111
89112 ########################################################################################## FoundationModel
90113 if "model" in cfg :
@@ -95,11 +118,18 @@ def _tuningmodel_from_cfg(self, cfg: Dict[str, Any]) -> TuningModel:
95118 # Support both string and enum types
96119 self .tuning .training .type = cfg ["mode" ] if isinstance (cfg ["mode" ], TrainingType ) else TrainingType (
97120 cfg ["mode" ])
98- if "hyper_parameters" in cfg :
99- # Ensure hyperparameters are in Dict[str, str] format
100- self .tuning .training .hyperparameters = {
101- str (k ): str (v ) for k , v in cfg ["hyper_parameters" ].items ()
102- }
121+
122+ if "training" in cfg :
123+ if "hyper_parameters" in cfg ["training" ]:
124+ # Ensure hyperparameters are in Dict[str, str] format
125+ self .tuning .training .hyperparameters = {
126+ str (k ): str (v ) for k , v in cfg ["training" ]["hyper_parameters" ].items ()
127+ }
128+ if "resources" in cfg ["training" ]:
129+ # Ensure resources are in Dict[str, str] format
130+ self .tuning .training .resources = {
131+ str (k ): str (v ) for k , v in cfg ["training" ]["resources" ].items ()
132+ }
103133
104134 return self .tuning
105135
@@ -138,7 +168,7 @@ async def register_functions(
138168 ) -> tuple [List [str ], List [str ], List [str ], List [str ]]:
139169 """Register function components and return entity/instance IDs."""
140170 if functions :
141- self .tuning .fcs = functions
171+ self .tuning .functions = functions
142172
143173 try :
144174 (rollout_entity_ids ,
@@ -163,31 +193,31 @@ async def register_functions(
163193
164194 async def upload_datasets (
165195 self ,
166- training_files : Optional [List [str ]] = None ,
167- validation_files : Optional [List [str ]] = None ,
196+ datasets : Optional [List [Dataset ]] = None ,
197+ training_files : Optional [Union [List [str ], str ]] = None ,
198+ validation_files : Optional [Union [List [str ], str ]] = None ,
168199 ) -> tuple [List [str ], List [str ]]:
169- """Upload datasets and return platform file IDs."""
170- if training_files :
171- self .tuning .datasets = Datasets (
172- name = '' ,
173- training_files = [FileSpec (path = f , descriptions = '' ) for f in training_files ],
174- validation_files = [FileSpec (path = f , descriptions = '' ) for f in
175- validation_files ] if validation_files else None )
200+ if datasets :
201+ self .tuning .datasets = datasets
176202
177203 try :
178- uploaded_training_ids , uploaded_validation_ids = await self .tuning .register_datasets ()
179- logger .info ("Datasets registration completed" )
204+ uploaded_training_ids , uploaded_validation_ids = await self .tuning .upload_datasets (
205+ training_files = training_files ,
206+ validation_files = validation_files ,
207+ )
208+ logger .info ("Datasets uploaded" )
180209 except Exception as e :
181- logger .error ("Dataset registration failed" , exc_info = True )
182- raise OSSUploadError ( "Dataset upload error" , error_code = 3300 ) from e
210+ logger .error ("Datasets upload failed" , exc_info = True )
211+ raise DatasetsError ( "Datasets upload error" , error_code = 3300 ) from e
183212
184213 return uploaded_training_ids , uploaded_validation_ids
185214
186215 def submit_job (
187216 self ,
188217 model : Optional [str ] = None ,
189- training_file_ids : Optional [Union [List [str ], str ]] = None ,
190- validation_file_ids : Optional [Union [List [str ], str ]] = None ,
218+ # training_file_ids: Optional[Union[List[str], str]] = None,
219+ # validation_file_ids: Optional[Union[List[str], str]] = None,
220+ datasets : Optional [List [Dataset ]] = None ,
191221 functions : Optional [Union [List [Union [
192222 RolloutFunctionComponent , RewardFunctionComponent , AgenticRLFunctionComponent ]],
193223 RolloutFunctionComponent , RewardFunctionComponent , AgenticRLFunctionComponent ]] = None ,
@@ -202,9 +232,9 @@ def submit_job(
202232 resolved_job_name = job_name or self .tuning .name
203233 job_name_with_suffix = f"{ resolved_job_name } -{ generate_random_id ()[:8 ]} "
204234
235+ # rollouts/rewards
205236 if functions :
206- self .tuning .fcs = functions
207-
237+ self .tuning .functions = functions
208238 try :
209239 rollouts = self .tuning .combine_ids_runtimes (type = FunctionType .ROLLOUT )
210240 rewards = self .tuning .combine_ids_runtimes (type = FunctionType .REWARD )
@@ -214,20 +244,33 @@ def submit_job(
214244 except Exception as e :
215245 logger .error (f"Tuning combine ids and runtimes failed: { str (e )} " , exc_info = True )
216246 raise
217-
247+ # names of functions
218248 if not self .tuning .check_function_names ():
219249 raise ValueErrorWithCode (
220250 "Duplicate function names detected. All function names must be unique." ,
221251 error_code = 3401
222252 )
223253
254+ # datasets
255+ datasets = datasets or self .tuning .datasets
256+ if not datasets :
257+ raise ValueError ("No datasets specified" )
258+ training_datasets = [ds for ds in datasets if ds .type == DatasetsType .TRAINING ]
259+ validation_datasets = [ds for ds in datasets if ds .type == DatasetsType .VALIDATION ]
260+
261+ # resources
262+ resource_config = kwargs .get ("resource_config" )
263+
224264 request = {
225265 "model" : model or self .tuning .model .name ,
226- "training_file_ids" : training_file_ids or self .tuning .datasets .uploaded_training_ids ,
227- "validation_file_ids" : validation_file_ids or self .tuning .datasets .uploaded_validation_ids ,
266+ # "training_file_ids": training_file_ids or self.tuning.datasets.uploaded_training_ids,
267+ # "validation_file_ids": validation_file_ids or self.tuning.datasets.uploaded_validation_ids,
268+ "training_datasets" : [ds .model_dump () for ds in training_datasets ],
269+ "validation_datasets" : [ds .model_dump () for ds in validation_datasets ],
228270 "rollout" : rollouts [0 ] if rollouts else None ,
229271 "rewards" : rewards ,
230272 "hyper_parameters" : hyper_parameters or self .tuning .training .hyperparameters ,
273+ "resource_config" : resource_config or self .tuning .training .resources ,
231274 "training_type" : str (self .tuning .training .type ),
232275 "job_name" : job_name_with_suffix ,
233276 }
@@ -252,8 +295,11 @@ async def run(
252295 model : Optional [str ] = None ,
253296
254297 # Datasets parameters
255- training_files : Optional [Union [List [str ], str ]] = None ,
256- validation_files : Optional [Union [List [str ], str ]] = None ,
298+ # training_files: Optional[Union[List[str], str]] = None,
299+ # validation_files: Optional[Union[List[str], str]] = None,
300+ #datasets: Optional[List[Dataset]] = None,
301+ training_datasets : Optional [List [TrainingDataset ]] = None ,
302+ validation_datasets : Optional [List [ValidationDataset ]] = None ,
257303
258304 # Path-driven parameters (auto-register & upload)
259305 functions : Optional [Union [List [Union [
@@ -263,7 +309,7 @@ async def run(
263309 # Common parameters
264310 hyper_parameters : Optional [Dict [str , str ]] = None ,
265311 job_name : Optional [str ] = None ,
266- workspace_dir : str = "./" ,
312+ # workspace_dir: str = "./",
267313 ** kwargs ,
268314 ) -> FineTune :
269315 """
@@ -276,13 +322,18 @@ async def run(
276322 lazy_load = True ,
277323 )
278324
325+ # await self.upload_datasets(
326+ # training_files=training_files,
327+ # validation_files=validation_files,
328+ # )
329+ datasets = list (training_datasets or []) + list (validation_datasets or [])
279330 await self .upload_datasets (
280- training_files = training_files ,
281- validation_files = validation_files ,
331+ datasets = datasets ,
282332 )
283333
284334 return self .submit_job (
285335 model = model ,
336+ datasets = datasets ,
286337 hyper_parameters = hyper_parameters ,
287338 job_name = job_name ,
288339 ** kwargs
@@ -365,26 +416,6 @@ def delete(
365416 ** kwargs ,
366417 )
367418
368- @classmethod
369- def stream_events (
370- cls ,
371- job_id : str ,
372- api_key : str = None ,
373- workspace : str = None ,
374- ** kwargs ,
375- ) -> Iterator [FineTuneEvent ]:
376- """Stream fine-tune job events."""
377- kwargs ['base_address' ] = DASHSCOPE_HTTP_BASE_URL
378-
379- responses = FineTunes .stream_events (
380- job_id ,
381- api_key = api_key ,
382- workspace = workspace ,
383- ** kwargs ,
384- )
385- for rsp in responses :
386- yield FineTuneEvent (** rsp )
387-
388419 @classmethod
389420 def logs (
390421 cls ,
0 commit comments