def __init__(self, num_clients, model, optimizer, ss_scheduler, data_path, model_path, train_dataloader, val_dataloader, test_dataloader, config, config_server):
    "Implement Server's orchestration and aggregation.\n\n        This is the main Server class, that actually implements orchestration\n        and aggregation, inheriting from `federated.Server`, which deals with\n        communication only.\n\n        The `train` method is central in FLUTE, as it defines good part of what\n        happens during training.\n\n        Args:\n            num_clients (int): total available clients.\n            model (torch.nn.Module): neural network model.\n            optimizer (torch.optim.Optimizer): optimizer.\n            ss_scheduler: scheduled sampling scheduler.\n            data_path (str): points to where data is.\n            model_path (str): points to where pretrained model is.\n            train_dataloader (torch.utils.data.DataLoader): dataloader for training\n            val_dataloader (torch.utils.data.DataLoader): dataloader for validation\n            test_dataloader (torch.utils.data.DataLoader): dataloader for test, can be None\n            config (dict): JSON style configuration parameters\n            config_server: deprecated, kept for API compatibility only.\n        "
    super().__init__()
    self.client_idx_list = list(range(num_clients))
    self.config = config
    server_config = config['server_config']
    decoder_config = config.get('decoder_config', None)
    self.max_iteration = server_config['max_iteration']
    self.do_clustering = server_config.get('clustering', False)
    self.num_clients_per_iteration = ([int(x) for x in server_config['num_clients_per_iteration'].split(',')] if isinstance(server_config['num_clients_per_iteration'], str) else [server_config['num_clients_per_iteration']])
    self.val_freq = server_config['val_freq']
    self.req_freq = server_config['rec_freq']
    self.evaluation = Evaluation(config, model_path, self.process_testvalidate, val_dataloader, test_dataloader)
    self.metrics = {'best_val_loss': float('inf'), 'best_val_acc': 0.0, 'best_test_loss': float('inf'), 'best_test_acc': 0.0}
    self.model_backup_freq = server_config.get('model_backup_freq', 100)
    self.worker_trainer_config = server_config.get('trainer_config', {})
    self.aggregate_median = server_config['aggregate_median']
    self.initial_lr_client = server_config.get('initial_lr_client', (- 1.0))
    self.lr_decay_factor = server_config.get('lr_decay_factor', 1.0)
    self.model_type = config['model_config']['model_type']
    self.quant_thresh = config['client_config'].get('quant_thresh', None)
    self.quant_bits = config['client_config'].get('quant_bits', 10)
    self.list_of_train_data = config['client_config']['data_config']['train']['list_of_train_data']
    self.data_path = data_path
    if ('train' in server_config['data_config']):
        max_grad_norm = server_config['data_config']['train'].get('max_grad_norm', None)
    else:
        max_grad_norm = None
    self.worker_trainer = ModelUpdater(model=model, optimizer=optimizer, ss_scheduler=ss_scheduler, train_dataloader=(train_dataloader if (train_dataloader is not None) else val_dataloader), val_dataloader=val_dataloader, max_grad_norm=max_grad_norm, anneal_config=server_config['annealing_config'], model_type=self.model_type, decoder_config=decoder_config)
    self.metrics['worker_trainer'] = self.worker_trainer
    self.server_replay_iterations = None
    self.server_trainer = None
    if (train_dataloader is not None):
        assert ('server_replay_config' in server_config), 'server_replay_config is not set'
        assert ('optimizer_config' in server_config['server_replay_config']), 'server-side replay training optimizer is not set'
        self.server_optimizer_config = server_config['server_replay_config']['optimizer_config']
        self.server_trainer_config = server_config['server_replay_config'].get('trainer_config', {})
        self.server_replay_iterations = server_config['server_replay_config']['server_iterations']
        self.server_trainer = Trainer(model=model, optimizer=None, ss_scheduler=ss_scheduler, train_dataloader=train_dataloader, server_replay_config=server_config['server_replay_config'], val_dataloader=None, max_grad_norm=server_config['server_replay_config'].get('max_grad_norm', server_config['data_config']['train'].get('max_grad_norm', None)), anneal_config=server_config['server_replay_config'].get('annealing_config', None))
    self.skip_model_update = False
    self.train_loss = 0.0
    self.model_path = model_path
    self.best_model_criterion = server_config['best_model_criterion']
    self.fall_back_to_best_model = server_config['fall_back_to_best_model']
    self.last_model_path = os.path.join(self.model_path, 'latest_model.tar')
    self.best_model_path = os.path.join(self.model_path, 'best_val_{}_model.tar'.format(self.best_model_criterion))
    self.log_path = os.path.join(self.model_path, 'status_log.json')
    self.cur_iter_no = 0
    self.lr_weight = 1.0
    self.losses = []
    self.no_label_updates = 0
    if server_config.get('resume_from_checkpoint', False):
        self.load_saved_status()
    self.decoder_config = decoder_config
    self.spm_model = server_config['data_config']['test'].get('spm_model', None)
    self.do_profiling = server_config.get('do_profiling', False)
    self.clients_in_parallel = config['client_config'].get('clients_in_parallel', None)
    StrategyClass = select_strategy(config['strategy'])
    self.strategy = StrategyClass('server', self.config, self.model_path)
    print_rank(f'Server successfully instantiated strategy {self.strategy}', loglevel=logging.DEBUG)
Implement Server's orchestration and aggregation.

This is the main Server class, that actually implements orchestration
and aggregation, inheriting from `federated.Server`, which deals with
communication only.

The `train` method is central in FLUTE, as it defines good part of what
happens during training.

Args:
    num_clients (int): total available clients.
    model (torch.nn.Module): neural network model.
    optimizer (torch.optim.Optimizer): optimizer.
    ss_scheduler: scheduled sampling scheduler.
    data_path (str): points to where data is.
    model_path (str): points to where pretrained model is.
    train_dataloader (torch.utils.data.DataLoader): dataloader for training
    val_dataloader (torch.utils.data.DataLoader): dataloader for validation
    test_dataloader (torch.utils.data.DataLoader): dataloader for test, can be None
    config (dict): JSON style configuration parameters
    config_server: deprecated, kept for API compatibility only.
def __init__(self, num_clients, model, optimizer, ss_scheduler, data_path, model_path, train_dataloader, val_dataloader, test_dataloader, config, config_server):
    "Implement Server's orchestration and aggregation.\n\n        This is the main Server class, that actually implements orchestration\n        and aggregation, inheriting from `federated.Server`, which deals with\n        communication only.\n\n        The `train` method is central in FLUTE, as it defines good part of what\n        happens during training.\n\n        Args:\n            num_clients (int): total available clients.\n            model (torch.nn.Module): neural network model.\n            optimizer (torch.optim.Optimizer): optimizer.\n            ss_scheduler: scheduled sampling scheduler.\n            data_path (str): points to where data is.\n            model_path (str): points to where pretrained model is.\n            train_dataloader (torch.utils.data.DataLoader): dataloader for training\n            val_dataloader (torch.utils.data.DataLoader): dataloader for validation\n            test_dataloader (torch.utils.data.DataLoader): dataloader for test, can be None\n            config (dict): JSON style configuration parameters\n            config_server: deprecated, kept for API compatibility only.\n        "
    super().__init__()
    self.client_idx_list = list(range(num_clients))
    self.config = config
    server_config = config['server_config']
    decoder_config = config.get('decoder_config', None)
    self.max_iteration = server_config['max_iteration']
    self.do_clustering = server_config.get('clustering', False)
    self.num_clients_per_iteration = ([int(x) for x in server_config['num_clients_per_iteration'].split(',')] if isinstance(server_config['num_clients_per_iteration'], str) else [server_config['num_clients_per_iteration']])
    self.val_freq = server_config['val_freq']
    self.req_freq = server_config['rec_freq']
    self.evaluation = Evaluation(config, model_path, self.process_testvalidate, val_dataloader, test_dataloader)
    self.metrics = {'best_val_loss': float('inf'), 'best_val_acc': 0.0, 'best_test_loss': float('inf'), 'best_test_acc': 0.0}
    self.model_backup_freq = server_config.get('model_backup_freq', 100)
    self.worker_trainer_config = server_config.get('trainer_config', {})
    self.aggregate_median = server_config['aggregate_median']
    self.initial_lr_client = server_config.get('initial_lr_client', (- 1.0))
    self.lr_decay_factor = server_config.get('lr_decay_factor', 1.0)
    self.model_type = config['model_config']['model_type']
    self.quant_thresh = config['client_config'].get('quant_thresh', None)
    self.quant_bits = config['client_config'].get('quant_bits', 10)
    self.list_of_train_data = config['client_config']['data_config']['train']['list_of_train_data']
    self.data_path = data_path
    if ('train' in server_config['data_config']):
        max_grad_norm = server_config['data_config']['train'].get('max_grad_norm', None)
    else:
        max_grad_norm = None
    self.worker_trainer = ModelUpdater(model=model, optimizer=optimizer, ss_scheduler=ss_scheduler, train_dataloader=(train_dataloader if (train_dataloader is not None) else val_dataloader), val_dataloader=val_dataloader, max_grad_norm=max_grad_norm, anneal_config=server_config['annealing_config'], model_type=self.model_type, decoder_config=decoder_config)
    self.metrics['worker_trainer'] = self.worker_trainer
    self.server_replay_iterations = None
    self.server_trainer = None
    if (train_dataloader is not None):
        assert ('server_replay_config' in server_config), 'server_replay_config is not set'
        assert ('optimizer_config' in server_config['server_replay_config']), 'server-side replay training optimizer is not set'
        self.server_optimizer_config = server_config['server_replay_config']['optimizer_config']
        self.server_trainer_config = server_config['server_replay_config'].get('trainer_config', {})
        self.server_replay_iterations = server_config['server_replay_config']['server_iterations']
        self.server_trainer = Trainer(model=model, optimizer=None, ss_scheduler=ss_scheduler, train_dataloader=train_dataloader, server_replay_config=server_config['server_replay_config'], val_dataloader=None, max_grad_norm=server_config['server_replay_config'].get('max_grad_norm', server_config['data_config']['train'].get('max_grad_norm', None)), anneal_config=server_config['server_replay_config'].get('annealing_config', None))
    self.skip_model_update = False
    self.train_loss = 0.0
    self.model_path = model_path
    self.best_model_criterion = server_config['best_model_criterion']
    self.fall_back_to_best_model = server_config['fall_back_to_best_model']
    self.last_model_path = os.path.join(self.model_path, 'latest_model.tar')
    self.best_model_path = os.path.join(self.model_path, 'best_val_{}_model.tar'.format(self.best_model_criterion))
    self.log_path = os.path.join(self.model_path, 'status_log.json')
    self.cur_iter_no = 0
    self.lr_weight = 1.0
    self.losses = []
    self.no_label_updates = 0
    if server_config.get('resume_from_checkpoint', False):
        self.load_saved_status()
    self.decoder_config = decoder_config
    self.spm_model = server_config['data_config']['test'].get('spm_model', None)
    self.do_profiling = server_config.get('do_profiling', False)
    self.clients_in_parallel = config['client_config'].get('clients_in_parallel', None)
    StrategyClass = select_strategy(config['strategy'])
    self.strategy = StrategyClass('server', self.config, self.model_path)
    print_rank(f'Server successfully instantiated strategy {self.strategy}', loglevel=logging.DEBUG)