You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Tune-AzureML-pipeline.md 6.1 kB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. # Tune - AzureML pipeline
  2. This example uses flaml to tune an Azure ML pipeline that fits a lightgbm classifier on the [sklearn breast cancer dataset](https://archive.ics.uci.edu/ml/datasets/Breast+Cancer+Wisconsin+(Diagnostic)).
  3. If you already have an Azure ML pipeline, you can use the approach to tune your pipeline with flaml.
  4. ## Prepare for tuning
  5. ### Requirements
  6. We recommend using conda or venv to create a virtual env to install the dependencies.
  7. ```bash
  8. # set up new conda environment
  9. conda create -n pipeline_tune python=3.8 pip=20.2 -y
  10. conda activate pipeline_tune
  11. # install azureml packages for runnig AzureML pipelines
  12. pip install azureml-core==1.39.0
  13. pip install azure-ml-component[notebooks]==0.9.10.post1
  14. pip install azureml-dataset-runtime==1.39.0
  15. # install hydra-core for passing AzureML pipeline parameters
  16. pip install hydra-core==1.1.1
  17. # install flaml
  18. pip install flaml[blendsearch,ray]==1.0.9
  19. ```
  20. ### Azure ML training pipeline
  21. Before we are ready for tuning, we must first have an Azure ML pipeline.
  22. In this example, we use the following toy pipeline for illustration.
  23. The pipeline consists of two steps: (1) data preparation and (2) model training.
  24. ![png](images/AzureML_train_pipeline.png).
  25. The [code example](https://github.com/microsoft/FLAML/tree/main/test/pipeline_tuning_example) discussed in the page is included in
  26. `test/pipeline_tuning_example/`.
  27. We will use the relative path in the rest of the page.
  28. ### Data
  29. The example data exsits in `data/data.csv`.
  30. It will be uploaded to AzureML workspace to be consumed by the training pipeline
  31. using the following code.
  32. ```python
  33. Dataset.File.upload_directory(
  34. src_dir=to_absolute_path(LOCAL_DIR / "data"),
  35. target=(datastore, "classification_data"),
  36. overwrite=True,
  37. )
  38. dataset = Dataset.File.from_files(path=(datastore, 'classification_data'))
  39. ```
  40. ### Configurations for the pipeline
  41. The pipeline configuration is defined in
  42. `configs/train_config.yaml`.
  43. ```yaml
  44. hydra:
  45. searchpath:
  46. - file://.
  47. aml_config:
  48. workspace_name: your_workspace_name
  49. resource_group: your_resource_group
  50. subscription_id: your_subscription_id
  51. cpu_target: cpucluster
  52. train_config:
  53. exp_name: sklearn_breast_cancer_classification
  54. test_train_ratio: 0.4
  55. learning_rate: 0.05
  56. n_estimators: 50
  57. ```
  58. ### Define and submit the pipeline
  59. The pipeline was defined in
  60. `submit_train_pipeline.py`.
  61. To submit the pipeline, please specify your AzureML resources
  62. in the `configs/train_config.yaml` and run
  63. ```bash
  64. cd test/pipeline_tuning_example
  65. python submit_train_pipeline.py
  66. ```
  67. To get the pipeline ready for HPO, in the training step,
  68. we need to log the metrics of interest to AzureML using
  69. ```python
  70. run.log(f"{data_name}_{eval_name}", result)
  71. ```
  72. ## Hyperparameter Optimization
  73. We are now ready to set up the HPO job for the AzureML pipeline, including:
  74. - config the HPO job,
  75. - set up the interaction between the HPO job and the training job.
  76. These two steps are done in `tuner/tuner_func.py`.
  77. ### Set up the tune job
  78. `tuner_func.tune_pipeline` sets up the search space, metric to optimize, mode, etc.
  79. ```python
  80. def tune_pipeline(concurrent_run=1):
  81. start_time = time.time()
  82. # config the HPO job
  83. search_space = {
  84. "train_config.n_estimators": flaml.tune.randint(50, 200),
  85. "train_config.learning_rate": flaml.tune.uniform(0.01, 0.5),
  86. }
  87. hp_metric = "eval_binary_error"
  88. mode = "max"
  89. num_samples = 2
  90. if concurrent_run > 1:
  91. import ray # For parallel tuning
  92. ray.init(num_cpus=concurrent_run)
  93. use_ray = True
  94. else:
  95. use_ray = False
  96. # launch the HPO job
  97. analysis = flaml.tune.run(
  98. run_with_config,
  99. config=search_space,
  100. metric=hp_metric,
  101. mode=mode,
  102. num_samples=num_samples, # number of trials
  103. use_ray=use_ray,
  104. )
  105. # get the best config
  106. best_trial = analysis.get_best_trial(hp_metric, mode, "all")
  107. metric = best_trial.metric_analysis[hp_metric][mode]
  108. print(f"n_trials={len(analysis.trials)}")
  109. print(f"time={time.time()-start_time}")
  110. print(f"Best {hp_metric}: {metric:.4f}")
  111. print(f"Best coonfiguration: {best_trial.config}")
  112. ```
  113. ### Interact with AzureML pipeline jobs
  114. The interaction between FLAML and AzureML pipeline jobs is in `tuner_func.run_with_config`.
  115. ```python
  116. def run_with_config(config: dict):
  117. """Run the pipeline with a given config dict
  118. """
  119. # pass the hyperparameters to AzureML jobs by overwriting the config file.
  120. overrides = [f"{key}={value}" for key, value in config.items()]
  121. print(overrides)
  122. run = submit_train_pipeline.build_and_submit_aml_pipeline(overrides)
  123. print(run.get_portal_url())
  124. # retrieving the metrics to optimize before the job completes.
  125. stop = False
  126. while not stop:
  127. # get status
  128. status = run._core_run.get_status()
  129. print(f'status: {status}')
  130. # get metrics
  131. metrics = run._core_run.get_metrics(recursive=True)
  132. if metrics:
  133. run_metrics = list(metrics.values())
  134. new_metric = run_metrics[0]['eval_binary_error']
  135. if type(new_metric) == list:
  136. new_metric = new_metric[-1]
  137. print(f'eval_binary_error: {new_metric}')
  138. tune.report(eval_binary_error=new_metric)
  139. time.sleep(5)
  140. if status == 'FAILED' or status == 'Completed':
  141. stop = True
  142. print("The run is terminated.")
  143. print(status)
  144. return
  145. ```
  146. Overall, to tune the hyperparameters of the AzureML pipeline, run:
  147. ```bash
  148. # the training job will run remotely as an AzureML job in both choices
  149. # run the tuning job locally
  150. python submit_tune.py --local
  151. # run the tuning job remotely
  152. python submit_tune.py --remote --subscription_id <your subscription_id> --resource_group <your resource_group> --workspace <your workspace>
  153. ```
  154. The local option runs the `tuner/tuner_func.py` in your local machine.
  155. The remote option wraps up the `tuner/tuner_func.py` as an AzureML component and
  156. starts another AzureML job to tune the AzureML pipeline.