Hi again CostlyOstrich36 ,
I just wanted to share what ended up working for me. Basically I worked it out both for Hydra (thanks CurvedHedgehog15 ) and for PytorchLightningCLI.
So, for PL-CLI, I used this construct so we don't have to modify our training scripts based on our experiment tracker
` from pytorch_lightning.utilities.cli import LightningCLI
from clearml import Task
class MyCLI(LightningCLI):
def before_instantiate_classes(self) -> None:
# init the task
task = Task.init()
# Connect the config to the task
# type(self.config) -> jsonargparse.Namespace
cfg_dict = self.config.as_dict()
cfg_dict = task.connect(cfg_dict)
cfg_dict = cfg_dict._to_dict()
self.config = jsonargparse.Namespace(**cfg_dict)
if name == "main":
MyCLI(...) One could also inherit from the SaveConfigCallback to have it upload the config.yaml to ClearML 🙂 Then, when hp-optimizing the model with
HyperParameterOptimizer you can use
ParameterSet([{"General/encoder_layers": x, "General/decoder_layers.0": x} for x in range(64, 512, 64)]) to work around the variable interpolation in the config file (
decoder_layers.0 = ${encoder_layers} ). This would be equivalent to
UniformIntegerParameterRange("encoder_layers", min_value=64, max_value=512, step_size=64) ` .
For Hydra, things are easier, but I had to use http://OmegaConf.to _container
instead of http://OmegaConf.to _object
to preserve the variable interpolation strings:
` @hydra(...)
def main(config: DictConfig) -> None:
# Init the task
task = Task.init(...)
# Connect the config to ClearML
out_config = OmegaConf.to_container(config)
out_config = task.connect(out_config, "HPO")
out_config = out_config._to_dict()
config= OmegaConf.create(out_config)
# Upload the config file to ClearML
task.upload_artifact(
"config file", HydraConfig.get().run.dir + "/.hydra/config.yaml"
) `