def METHOD_NAME(self, data_inst, validate_data=None):
    if hasattr(
            data_inst,
            'partitions') and data_inst.partitions is not None:
        self.default_table_partitions = data_inst.partitions
        LOGGER.debug(
            'reset default partitions is {}'.format(
                self.default_table_partitions))
    train_ds = self.prepare_dataset(data_inst, data_type='train')
    if validate_data is not None:
        val_ds = self.prepare_dataset(validate_data, data_type='validate')
    else:
        val_ds = None
    self.callback_list.on_train_begin(train_ds, val_ds)
    if not self.component_properties.is_warm_start:
        self._build_model()
        epoch_offset = 0
    else:
        self.callback_warm_start_init_iter(self.history_iter_epoch)
        epoch_offset = self.history_iter_epoch + 1
    batch_size = len(train_ds) if self.batch_size == - \
        1 else self.batch_size
    for cur_epoch in range(epoch_offset, epoch_offset + self.epochs):
        self.iter_epoch = cur_epoch
        for batch_idx, batch_data in enumerate(
                DataLoader(train_ds, batch_size=batch_size)):
            self.model.train(batch_data, cur_epoch, batch_idx)
        self.callback_list.on_epoch_end(cur_epoch)
        if self.callback_variables.stop_training:
            LOGGER.debug('early stopping triggered')
            break
        is_converge = self.transfer_variable.is_converge.get(
            idx=0, suffix=(cur_epoch,))
        if is_converge:
            LOGGER.debug(
                "Training process is converged in epoch {}".format(cur_epoch))
            break
    self.callback_list.on_train_end()