Skip to content

Commit

Permalink
7601 fix mlflow artifacts (#7604)
Browse files Browse the repository at this point in the history
Fixes #7601 .

### Description

Support not save artifacts.

### Types of changes
<!--- Put an `x` in all the boxes that apply, and remove the not
applicable items -->
- [x] Non-breaking change (fix or new feature that would not break
existing functionality).
- [ ] Breaking change (fix or new feature that would cause existing
functionality to change).
- [ ] New tests added to cover the changes.
- [x] Integration tests passed locally by running `./runtests.sh -f -u
--net --coverage`.
- [x] Quick tests passed locally by running `./runtests.sh --quick
--unittests --disttests`.
- [x] In-line docstrings updated.
- [ ] Documentation updated, tested `make html` command in the `docs/`
folder.

---------

Signed-off-by: binliu <[email protected]>
Co-authored-by: Nic Ma <[email protected]>
Co-authored-by: YunLiu <[email protected]>
  • Loading branch information
3 people authored Apr 12, 2024
1 parent 3856c45 commit da3ecdd
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 20 deletions.
17 changes: 13 additions & 4 deletions monai/bundle/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,10 +778,19 @@ def run(
https://docs.python.org/3/library/logging.config.html#logging.config.fileConfig.
Default to None.
tracking: if not None, enable the experiment tracking at runtime with optionally configurable and extensible.
if "mlflow", will add `MLFlowHandler` to the parsed bundle with default tracking settings,
if other string, treat it as file path to load the tracking settings.
if `dict`, treat it as tracking settings.
will patch the target config content with `tracking handlers` and the top-level items of `configs`.
If "mlflow", will add `MLFlowHandler` to the parsed bundle with default tracking settings where a set of
common parameters shown below will be added and can be passed through the `override` parameter of this method.
- ``"output_dir"``: the path to save mlflow tracking outputs locally, default to "<bundle root>/eval".
- ``"tracking_uri"``: uri to save mlflow tracking outputs, default to "/output_dir/mlruns".
- ``"experiment_name"``: experiment name for this run, default to "monai_experiment".
- ``"run_name"``: the name of current run.
- ``"save_execute_config"``: whether to save the executed config files. It can be `False`, `/path/to/artifacts`
or `True`. If set to `True`, will save to the default path "<bundle_root>/eval". Default to `True`.
If other string, treat it as file path to load the tracking settings.
If `dict`, treat it as tracking settings.
Will patch the target config content with `tracking handlers` and the top-level items of `configs`.
for detailed usage examples, please check the tutorial:
https://github.com/Project-MONAI/tutorials/blob/main/experiment_management/bundle_integrate_mlflow.ipynb.
args_file: a JSON or YAML file to provide default values for `run_id`, `meta_file`,
Expand Down
6 changes: 3 additions & 3 deletions monai/bundle/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
"experiment_name": "monai_experiment",
"run_name": None,
# may fill it at runtime
"execute_config": None,
"save_execute_config": True,
"is_not_rank0": (
"$torch.distributed.is_available() \
and torch.distributed.is_initialized() and torch.distributed.get_rank() > 0"
Expand All @@ -125,7 +125,7 @@
"tracking_uri": "@tracking_uri",
"experiment_name": "@experiment_name",
"run_name": "@run_name",
"artifacts": "@execute_config",
"artifacts": "@save_execute_config",
"iteration_log": True,
"epoch_log": True,
"tag_name": "train_loss",
Expand All @@ -148,7 +148,7 @@
"tracking_uri": "@tracking_uri",
"experiment_name": "@experiment_name",
"run_name": "@run_name",
"artifacts": "@execute_config",
"artifacts": "@save_execute_config",
"iteration_log": False,
"close_on_complete": True,
},
Expand Down
26 changes: 16 additions & 10 deletions monai/bundle/workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,13 +506,19 @@ def patch_bundle_tracking(parser: ConfigParser, settings: dict) -> None:
parser[k] = v
# save the executed config into file
default_name = f"config_{time.strftime('%Y%m%d_%H%M%S')}.json"
filepath = parser.get("execute_config", None)
if filepath is None:
if "output_dir" not in parser:
# if no "output_dir" in the bundle config, default to "<bundle root>/eval"
parser["output_dir"] = f"{EXPR_KEY}{ID_REF_KEY}bundle_root + '/eval'"
# experiment management tools can refer to this config item to track the config info
parser["execute_config"] = parser["output_dir"] + f" + '/{default_name}'"
filepath = os.path.join(parser.get_parsed_content("output_dir"), default_name)
Path(filepath).parent.mkdir(parents=True, exist_ok=True)
parser.export_config_file(parser.get(), filepath)
# Users can set the `save_execute_config` to `False`, `/path/to/artifacts` or `True`.
# If set to False, nothing will be recorded. If set to True, the default path will be logged.
# If set to a file path, the given path will be logged.
filepath = parser.get("save_execute_config", True)
if filepath:
if isinstance(filepath, bool):
if "output_dir" not in parser:
# if no "output_dir" in the bundle config, default to "<bundle root>/eval"
parser["output_dir"] = f"{EXPR_KEY}{ID_REF_KEY}bundle_root + '/eval'"
# experiment management tools can refer to this config item to track the config info
parser["save_execute_config"] = parser["output_dir"] + f" + '/{default_name}'"
filepath = os.path.join(parser.get_parsed_content("output_dir"), default_name)
Path(filepath).parent.mkdir(parents=True, exist_ok=True)
parser.export_config_file(parser.get(), filepath)
else:
parser["save_execute_config"] = None
6 changes: 3 additions & 3 deletions tests/test_fl_monai_algo.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
tracking={
"handlers_id": DEFAULT_HANDLERS_ID,
"configs": {
"execute_config": f"{_data_dir}/config_executed.json",
"save_execute_config": f"{_data_dir}/config_executed.json",
"trainer": {
"_target_": "MLFlowHandler",
"tracking_uri": path_to_uri(_data_dir) + "/mlflow_override",
Expand Down Expand Up @@ -201,7 +201,7 @@ def test_train(self, input_params):
algo.finalize()

# test experiment management
if "execute_config" in algo.train_workflow.parser:
if "save_execute_config" in algo.train_workflow.parser:
self.assertTrue(os.path.exists(f"{_data_dir}/mlflow_override"))
shutil.rmtree(f"{_data_dir}/mlflow_override")
self.assertTrue(os.path.exists(f"{_data_dir}/config_executed.json"))
Expand All @@ -224,7 +224,7 @@ def test_evaluate(self, input_params):
algo.evaluate(data=data, extra={})

# test experiment management
if "execute_config" in algo.eval_workflow.parser:
if "save_execute_config" in algo.eval_workflow.parser:
self.assertGreater(len(list(glob.glob(f"{_data_dir}/mlflow_*"))), 0)
for f in list(glob.glob(f"{_data_dir}/mlflow_*")):
shutil.rmtree(f)
Expand Down

0 comments on commit da3ecdd

Please sign in to comment.