    def _run_train(self, resume_checkpoint_path: str = None):
        """
        Main training entry point.
        It is not recommended for users to use it unless over rewriting Trainer.
        Instead, it is recommended to use `trainer.train()` to start training.

        Args:
            resume_checkpoint_path (`str`):
                Last checkpoint path.
        """
        set_seed(self.configs.seed)

        self.trainercontrol = TrainerControl()
        self._load_before_train(resume_checkpoint_path)

        if self.configs.device_str == "cuda":
            self.model = nn.DataParallel(self.model)
        else:
            self.model = self.model.to(self.configs.device)
        model = self.model

        # Keeping track whether we can can len() on the dataset or not
        # train_dataset_is_sized = isinstance(self.train_dataset, collections.abc.Sized)

        train_dataloader = self.get_train_dataloader()

        total_train_batch_size = self.configs.train_batch_size
        # if train_dataset_is_sized:
        # num_update_steps_per_epoch = len(train_dataloader)
        num_update_steps_per_epoch = len(self.train_dataset)
        num_update_steps_per_epoch = max(num_update_steps_per_epoch, 1)

        train_last_epoch = self.epoch
        num_train_epochs = math.ceil(self.configs.epoch_num - train_last_epoch)
        num_train_steps = math.ceil(num_train_epochs * num_update_steps_per_epoch)
        self.setup_before_train(num_training_steps=num_train_steps, init_lr=self.lr_value)
        trainer_log.info("***** Running training *****")
        trainer_log.info("  Num Epochs = %d", num_train_epochs)
        trainer_log.info("  Total train batch size  = %d", total_train_batch_size)
        trainer_log.info("****************************")

        if is_main_process():
            trainer_log.warning(self.configs)

        logs = self._create_logs()
        self.callbacks.on_train_begin(logs)
        for epoch in range(train_last_epoch + 1, self.configs.epoch_num + 1):
            self.epoch = logs["epoch"] = epoch
            self.set_train_mode(model)
            self._reset_controller()
            self.optimizer.zero_grad()
            self.callbacks.on_epoch_begin(self.epoch, logs)
            self.loss_metric.reset()
            self.metric.reset()
            for step, inputs in enumerate(train_dataloader):
                self.callbacks.on_train_batch_begin(inputs, logs)
                inputs = self.prepare_inputs(inputs)
                step_logs = self.train_step(model, inputs)  # , train_dataloader)
                logs["lr"] = self.lr_scheduler.get_last_lr()[0]
                logs["global_step"] += 1
                logs.update(step_logs)
                self.callbacks.on_train_batch_end(tuple(inputs), logs)
                self._may_evaluate(model, logs, step)
            self._may_evaluate(model, logs)
            self.callbacks.on_epoch_end(self.epoch, logs)
            self.loss_value = logs["epoch_loss"]
            self.metric_value = logs["epoch_metric"]
            self.lr_value = logs["lr"]
            self._create_training_summary(
                finetuned_from=resume_checkpoint_path,
                resumed_from_epoch=train_last_epoch if train_last_epoch != 0 else None,
                num_train_epochs=self.epoch - train_last_epoch,
                current_epoch=self.epoch,
                end_lr=self.lr_value,
                loss={"type": self.configs.loss, "value": round(self.loss_value, 3)},
                metric={"type": self.configs.metric, "value": round(self.metric_value, 3)}
            )
            if self.trainercontrol.should_training_stop:
                break
            if self.trainercontrol.should_save:
                self.save(
                    path=Path(self.configs.output_dir).joinpath("epoch_" + str(self.epoch)),
                    overwrite=self.configs.overwrite_output_dir
                )
        trainer_log.info("\nTraining completed.\n")
        self.callbacks.on_train_end(logs)
        self.save(
            path=Path(self.configs.output_dir).joinpath("final_epoch"),
            overwrite=self.configs.overwrite_output_dir
        )
Main training entry point.
It is not recommended for users to use it unless over rewriting Trainer.
Instead, it is recommended to use `trainer.train()` to start training.

Args:
resume_checkpoint_path (`str`):
Last checkpoint path.
towhee/trainer/trainer.py