Compact_Facts / utils /argparse.py
khulnasoft's picture
Upload 108 files
4fb0bd1 verified
import os
import logging
import configargparse
from utils.logging_utils import init_logger
from utils.parse_action import StoreLoggingLevelAction
class ConfigurationParer():
"""This class defines customized configuration parser
"""
def __init__(self,
config_file_parser_class=configargparse.YAMLConfigFileParser,
formatter_class=configargparse.ArgumentDefaultsHelpFormatter,
**kwargs):
"""This funtion decides config parser and formatter
Keyword Arguments:
config_file_parser_class {configargparse.ConfigFileParser} -- config file parser (default: {configargparse.YAMLConfigFileParser})
formatter_class {configargparse.ArgumentDefaultsHelpFormatter} -- config formatter (default: {configargparse.ArgumentDefaultsHelpFormatter})
"""
self.parser = configargparse.ArgumentParser(config_file_parser_class=config_file_parser_class,
formatter_class=formatter_class,
**kwargs)
def add_save_cfgs(self):
"""This function adds saving path arguments: config file, model file...
"""
# config file configurations
group = self.parser.add_argument_group('Config-File')
group.add('-config_file', '--config_file', required=False, is_config_file_arg=True, help='config file path')
# model file configurations
group = self.parser.add_argument_group('Model-File')
group.add('-save_dir', '--save_dir', type=str, required=True, help='directory for saving checkpoints.')
def add_data_cfgs(self):
"""This function adds dataset arguments: data file path...
"""
self.parser.add('-data_dir', '--data_dir', type=str, required=True, help='dataset directory.')
self.parser.add('-train_file', '--train_file', type=str, required=False, help='train data file.')
self.parser.add('-dev_file', '--dev_file', type=str, required=False, help='dev data file.')
self.parser.add('-test_file', '--test_file', type=str, required=False, help='test data file.')
self.parser.add('-conjunctions_file', '--conjunctions_file', type=str, required=False, help='test conjunctions data file (produced by OpenIE6).')
self.parser.add('-ent_rel_file', '--ent_rel_file', type=str, required=False, help='entity and relation file.')
self.parser.add('-rel_file', '--rel_file', type=str, required=False, help='relation only file.')
self.parser.add('-max_sent_len', '--max_sent_len', type=int, default=200, help='max sentence length.')
self.parser.add('-max_wordpiece_len', '--max_wordpiece_len', type=int, default=512, help='max sentence length.')
self.parser.add('-test', '--test', action='store_true', help='testing mode')
def add_model_cfgs(self):
"""This function adds model (network) arguments: embedding, hidden unit...
"""
# embedding configurations
group = self.parser.add_argument_group('Embedding')
group.add('-embedding_model',
'--embedding_model',
type=str,
choices=["bert", "pretrained"],
default="bert",
help='embedding model.')
group.add('-bert_model_name', '--bert_model_name', type=str, required=False, help='bert model name.')
group.add('-pretrained_model_name',
'--pretrained_model_name',
type=str,
required=False,
help='pretrained model name.')
group.add('-bert_output_size', '--bert_output_size', type=int, default=768, help='bert output size.')
group.add('-bert_dropout', '--bert_dropout', type=float, default=0.1, help='bert dropout rate.')
group.add('--fine_tune', '--fine_tune', action='store_true', help='fine-tune pretrained model.')
# biaffine model
group = self.parser.add_argument_group('Biaffine')
group.add('-max_span_length', '--max_span_length', type=int, default=10, help='maximum span length.')
group.add('-mlp_hidden_size', '--mlp_hidden_size', type=int, default=768, help='mlp hidden units size.')
group.add('-dropout', '--dropout', type=float, default=0.5, help='dropout rate.')
group.add('-separate_threshold',
'--separate_threshold',
type=float,
default=1.07,
help='the threshold for separating spans.')
group.add('-logit_dropout',
'--logit_dropout',
type=float,
default=0.1,
help='logit dropout rate for robustness.')
def add_optimizer_cfgs(self):
"""This function adds optimizer arguments
"""
# gradient strategy
self.parser.add('-gradient_clipping',
'--gradient_clipping',
type=float,
default=1.0,
help='gradient clipping threshold.')
# learning rate
self.parser.add('--learning_rate',
'-learning_rate',
type=float,
default=3e-5,
help="Starting learning rate. "
"Recommended settings: sgd = 1, adagrad = 0.1, "
"adadelta = 1, adam = 0.001")
self.parser.add('--bert_learning_rate',
'-bert_learning_rate',
type=float,
default=3e-5,
help="learning rate for bert, should be smaller than followed parts.")
self.parser.add('-lr_decay_rate',
'--lr_decay_rate',
type=float,
default=0.9,
help='learn rate of layers decay rate.')
# Adam configurations
group = self.parser.add_argument_group('Adam')
group.add('-adam_beta1',
'--adam_beta1',
type=float,
default=0.9,
help="The beta1 parameter used by Adam. "
"Almost without exception a value of 0.9 is used in "
"the literature, seemingly giving good results, "
"so we would discourage changing this value from "
"the default without due consideration.")
group.add('-adam_beta2',
'--adam_beta2',
type=float,
default=0.999,
help='The beta2 parameter used by Adam. '
'Typically a value of 0.999 is recommended, as this is '
'the value suggested by the original paper describing '
'Adam, and is also the value adopted in other frameworks '
'such as Tensorflow and Kerras, i.e. see: '
'https://www.tensorflow.org/api_docs/python/tf/train/Adam'
'Optimizer or '
'https://keras.io/optimizers/ . '
'Whereas recently the paper "Attention is All You Need" '
'suggested a value of 0.98 for beta2, this parameter may '
'not work well for normal models / default '
'baselines.')
group.add('-adam_epsilon', '--adam_epsilon', type=float, default=1e-6, help='adam epsilon')
group.add('-adam_weight_decay_rate',
'--adam_weight_decay_rate',
type=float,
default=0.0,
help='adam weight decay rate.')
group.add('-adam_bert_weight_decay_rate',
'--adam_bert_weight_decay_rate',
type=float,
default=0.0,
help='adam weight decay rate of Bert module.')
def add_run_cfgs(self):
"""This function adds running arguments
"""
# training configurations
group = self.parser.add_argument_group('Training')
group.add('-seed', '--seed', type=int, default=5216, help='radom seed.')
group.add('-epochs', '--epochs', type=int, default=1000, help='training epochs.')
group.add('-pretrain_epochs', '--pretrain_epochs', type=int, default=0, help='pretrain epochs.')
group.add('-warmup_rate', '--warmup_rate', type=float, default=0.0, help='warmup rate.')
group.add('-early_stop', '--early_stop', type=int, default=50, help='early stop threshold.')
group.add('-train_batch_size', '--train_batch_size', type=int, default=200, help='batch size during training.')
group.add('-gradient_accumulation_steps',
'--gradient_accumulation_steps',
type=int,
default=1,
help='Number of updates steps to accumulate before performing a backward/update pass.')
# testing configurations
group = self.parser.add_argument_group('Testing')
group.add('-test_batch_size', '--test_batch_size', type=int, default=100, help='batch size during testing.')
group.add('-validate_every',
'--validate_every',
type=int,
default=20000,
help='output result every n samples during validating.')
# gpu configurations
group = self.parser.add_argument_group('GPU')
group.add('-device',
'--device',
type=int,
default=-1,
help='cpu: device = -1, gpu: gpu device id(device >= 0).')
# logging configurations
group = self.parser.add_argument_group('logging')
group.add('-root_log_level',
'--root_log_level',
type=str,
action=StoreLoggingLevelAction,
choices=StoreLoggingLevelAction.CHOICES,
default="DEBUG",
help='root logging out level.')
group.add('-console_log_level',
'--console_log_level',
type=str,
action=StoreLoggingLevelAction,
choices=StoreLoggingLevelAction.CHOICES,
default="NOTSET",
help='console logging output level.')
group.add('-log_file', '--log_file', type=str, required=True, help='logging file during running.')
group.add('-file_log_level',
'--file_log_level',
type=str,
action=StoreLoggingLevelAction,
choices=StoreLoggingLevelAction.CHOICES,
default="NOTSET",
help='file logging output level.')
group.add('-logging_steps', '--logging_steps', type=int, default=10, help='Logging every N update steps.')
def parse_args(self):
"""This function parses arguments and initializes logger
Returns:
dict -- config arguments
"""
cfg = self.parser.parse_args()
if not os.path.exists(cfg.save_dir):
os.makedirs(cfg.save_dir)
cfg.last_model_path = os.path.join(cfg.save_dir, 'last_model')
cfg.models = os.path.join(cfg.save_dir, 'models')
cfg.constituent_model_dir = os.path.join(cfg.models, 'constituent')
cfg.relation_model_dir = os.path.join(cfg.models, 'relation')
cfg.constituent_vocab = os.path.join(cfg.constituent_model_dir, "vocabulary.pickle")
cfg.relation_vocab = os.path.join(cfg.relation_model_dir, "vocabulary.pickle")
cfg.constituent_model_path = os.path.join(cfg.constituent_model_dir, 'ce_model')
cfg.relation_model_path = os.path.join(cfg.relation_model_dir, 'cl_model')
if "carb" in cfg.test_file:
cfg.separate_threshold = 1.25
cfg.carb = True
if "wire57" in cfg.test_file:
cfg.separate_threshold = 1.05
cfg.wire57 = True
assert os.path.exists(cfg.data_dir), f"dataset directory {cfg.data_dir} not exists !!!"
for file in ['train_file', 'dev_file', 'test_file']:
if getattr(cfg, file, None) is not None:
setattr(cfg, file, os.path.join(cfg.data_dir, getattr(cfg, file, None)))
if getattr(cfg, 'log_file', None) is not None:
cfg.log_file = os.path.join(cfg.save_dir, cfg.log_file)
assert not os.path.exists(cfg.log_file), f"log file {cfg.log_file} exists !!!"
init_logger(root_log_level=getattr(cfg, 'root_log_level', logging.DEBUG),
console_log_level=getattr(cfg, 'console_log_level', logging.NOTSET),
log_file=getattr(cfg, 'log_file', None),
log_file_level=getattr(cfg, 'log_file_level', logging.NOTSET))
return cfg
def format_values(self):
return self.parser.format_values()