Is `hparams` really a good practice?
❓ Questions and Help
I am a bit confused about good practices in PyTorchLightning, having in mind hparams in particular. I will provide some of my thoughts about this topic.  The docs says:
# YES
model = LitModel(hparams)
trainer = Trainer.from_argparse_args(hparams, early_stopping_callback=...)

# NO
# model = LitModel(learning_rate=hparams.learning_rate, ...)
# trainer = Trainer(gpus=hparams.gpus, ...)


Does it allow to parametrize EarlyStopping callback e.g. patience? The only way I can think of is using bad practice.

def main(hparams):
    model = LitModel(hparams)

    early_stop_callback = EarlyStopping(
        monitor='val_loss',
        mode='min',
        patience=hparams.patience,
    )

    trainer = Trainer.from_argparse_args(
        hparams,
        early_stop_callback=early_stop_callback,
    )

    trainer.fit(model)

if __name__ == '__main__':
    parser = ArgumentParser()
    parser.add_argument('--patience', type=int, default=5)

    parser = LitModel.add_model_specific_args(parser)
    parser = Trainer.add_argparse_args(parser)
    hparams = parser.parse_args()

    main(hparams)

Please let me know how to do it in a nice way.

What does happen if Trainer and LitModel both use the same argument name for different purposes? In the docs, they are combined into a parent parser.

    parser = ArgumentParser()
    parser = Trainer.add_argparse_args(parser)

    # figure out which model to use
    parser.add_argument('--model_name', type=str, default='gan', help='gan or mnist')

    # THIS LINE IS KEY TO PULL THE MODEL NAME
    temp_args, _ = parser.parse_known_args()

    # let the model add what it wants
    if temp_args.model_name == 'gan':
        parser = GoodGAN.add_model_specific_args(parser)
    elif temp_args.model_name == 'mnist':
        parser = LitMNIST.add_model_specific_args(parser)

    args = parser.parse_args()

Perhaps a good practice is to parse them separately?

I don't think that using add_model_specific_args static method & pass only hparams into __init__  is a good idea.

class LitModel(LightningModule):
    def __init__(self, hparams):
        super().__init__()
        self.hparams = hparams

    @staticmethod
    def add_model_specific_args(parent_parser):
        parser = ArgumentParser(parents=[parent_parser], add_help=False)
        parser.add_argument(...)
        ...
        return parser

a) If I properly assigned  __init__ arguments into self, then IDE would suggest to me the Unresolved reference error before running the code. It happened to me many times to have some leftovers hanging out because of this hparams.
b) Basically add_model_specific_args requires me to track all occurrences of self.hparams in the code visually! If I properly assigned __init__ arguments into self, I would need just to take a simple look at the __init__ section.
I think I know the reasons why hparams was introduced (easy tracking in tensorboard or rapid research), but I believe that this concept should be reconsidered.