def parse_args(parser):
    """
    Parse commandline arguments.
    """

    parser.add_argument('-o', '--output_directory', type=str, default='logs', required=True, help='Directory to save checkpoints')
    parser.add_argument('-d', '--dataset-path', type=str, default='filelists', help='Path to dataset')
    parser.add_argument('--log-file', type=str, default='nvlog.json', help='Filename for logging')
    parser.add_argument('--latest-checkpoint-file', type=str, default='checkpoint_latest.pt', help='Store the latest checkpoint in each epoch')
    parser.add_argument('--phrase-path', type=str, default=None, help='Path to phrase sequence file used for sample generation')
    parser.add_argument('--tacotron2-checkpoint', type=str, default=None, help='Path to pre-trained Tacotron2 checkpoint for sample generation')

    # training
    training = parser.add_argument_group('training setup')
    training.add_argument('--epochs', type=int, required=True, help='Number of total epochs to run')
    training.add_argument('--epochs-per-alignment', type=int, default=10, help='Number of epochs per alignment')
    training.add_argument('--epochs-per-checkpoint', type=int, default=50, help='Number of epochs per checkpoint')
    training.add_argument('--seed', type=int, default=1234, help='Seed for PyTorch random number generators')
    training.add_argument('--dynamic-loss-scaling', type=bool, default=True, help='Enable dynamic loss scaling')
    training.add_argument('--amp-run', action='store_true', help='Enable AMP')
    training.add_argument('--cudnn-enabled', action='store_true', help='Enable cudnn')
    training.add_argument('--cudnn-benchmark', action='store_true', help='Run cudnn benchmark')
    training.add_argument('--disable-uniform-initialize-bn-weight', action='store_true', help='disable uniform initialization of batchnorm layer weight')

    optimization = parser.add_argument_group('optimization setup')
    optimization.add_argument('--use-saved-learning-rate', default=False, type=bool)
    optimization.add_argument('--init-lr', '--initial-learning-rate', default=1e-3, type=float, required=True, help='Initial learing rate')
    optimization.add_argument('--final-lr', '--final-learning-rate', default=1e-5, type=float, required=True, help='Final earing rate')
    optimization.add_argument('--weight-decay', default=1e-6, type=float, help='Weight decay')
    optimization.add_argument('--grad-clip-thresh', default=1.0, type=float, help='Clip threshold for gradients')
    optimization.add_argument('-bs', '--batch-size', default=32, type=int, required=True, help='Batch size per GPU')

    # dataset parameters
    dataset = parser.add_argument_group('dataset parameters')
    dataset.add_argument('--load-mel-from-disk', action='store_true', help='Loads mel spectrograms from disk instead of computing them on the fly')
    dataset.add_argument('--training-anchor-dirs', default=['ljs_mel_text_train_filelist.txt'], type=str, nargs='*', help='Path to training filelist')
    dataset.add_argument('--validation-anchor-dirs', default=['ljs_mel_text_val_filelist.txt'], type=str, nargs='*', help='Path to validation filelist')
    dataset.add_argument('--text-cleaners', nargs='*', default=['basic_cleaners'], type=str, help='Type of text cleaners for input text')

    # audio parameters
    audio = parser.add_argument_group('audio parameters')
    audio.add_argument('--max-wav-value', default=32768.0, type=float, help='Maximum audiowave value')
    audio.add_argument('--sampling-rate', default=22050, type=int, help='Sampling rate')
    audio.add_argument('--filter-length', default=2048, type=int, help='Filter length')
    audio.add_argument('--hop-length', default=275, type=int, help='Hop (stride) length')
    audio.add_argument('--win-length', default=1100, type=int, help='Window length')
    audio.add_argument('--mel-fmin', default=125.0, type=float, help='Minimum mel frequency')
    audio.add_argument('--mel-fmax', default=7600.0, type=float, help='Maximum mel frequency')

    distributed = parser.add_argument_group('distributed setup')
    distributed.add_argument('--distributed-run', default=False, type=bool, help='enable distributed run')
    distributed.add_argument('--rank', default=0, type=int, help='Rank of the process, do not set! Done by multiproc module')
    distributed.add_argument('--world-size', default=1, type=int, help='Number of processes, do not set! Done by multiproc module')
    distributed.add_argument('--dist-url', type=str, default='tcp://localhost:23456', help='Url used to set up distributed training')
    distributed.add_argument('--group-name', type=str, default='group_name', required=False, help='Distributed group name')
    distributed.add_argument('--dist-backend', default='nccl', type=str, choices={'nccl'}, help='Distributed run backend')

    return parser