Skip to content

Commit 483d8b4

Browse files
author
zhansheng.lzs
committed
agentic-rl: merge from moe-dashscope-sdk-python
1 parent f584dc2 commit 483d8b4

54 files changed

Lines changed: 3833 additions & 3068 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

dashscope/finetune/agentic_rl.py

Lines changed: 103 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222
from dashscope.finetune.finetunes import FineTunes
2323

2424
from dashscope.finetune.reinforcement.common.errors import (
25-
OSSUploadError, RegistrationError, ValidationError, IOErrorWithCode, RuntimeErrorWithCode, ValueErrorWithCode,
25+
OSSUploadError, RegistrationError, ValidationError, IOErrorWithCode, RuntimeErrorWithCode, ValueErrorWithCode, DatasetsError
2626
)
2727
from dashscope.finetune.reinforcement import logger
2828
from dashscope.finetune.reinforcement import DASHSCOPE_HTTP_BASE_URL
2929
from 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
3132
from dashscope.finetune.reinforcement import AgenticRLTuning, TuningModel
3233
from 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

Comments
 (0)