class_docstr: NoneTrainer is a trainer that does not train a model, only runs evaluation.
class_docstr_tok: ["NoneTrainer","is","a","trainer","that","does","not","train","a","model",",","only","runs","evaluation","."]
code: def train(
      self,
      training_set: Dataset,
      validation_set: Optional[Dataset] = None,
      test_set: Optional[Dataset] = None,
      save_path: str = "model",
      return_state_dict: bool = False,
      **kwargs,
  ):
      output_features = self.model.output_features
  
      # ====== Setup file names =======
      tensorboard_log_dir = None
      if self.is_coordinator():
          os.makedirs(save_path, exist_ok=True)
          tensorboard_log_dir = os.path.join(save_path, "logs")
  
      self.callback(
          lambda c: c.on_trainer_train_setup(
              self, save_path, self.is_coordinator()
          ),
          coordinator_only=False,
      )
  
      train_summary_writer = None
      validation_summary_writer = None
      test_summary_writer = None
      if (
          self.is_coordinator()
          and not self.skip_save_log
          and tensorboard_log_dir
      ):
          train_summary_writer = SummaryWriter(
              os.path.join(tensorboard_log_dir, TRAINING)
          )
          if validation_set is not None and validation_set.size > 0:
              validation_summary_writer = SummaryWriter(
                  os.path.join(tensorboard_log_dir, VALIDATION)
              )
          if test_set is not None and test_set.size > 0:
              test_summary_writer = SummaryWriter(
                  os.path.join(tensorboard_log_dir, TEST)
              )
  
      set_random_seed(self.random_seed)
  
      progress_tracker = get_new_progress_tracker(
          batch_size=self.batch_size,
          learning_rate=self.base_learning_rate,
          best_eval_metric_value=get_initial_validation_value(
              self.validation_metric
          ),
          best_increase_batch_size_eval_metric=float("inf"),
          output_features=output_features,
      )
  
      # When running with Ray, we only need to return the state dict, as it's faster and cheaper to send the
      # state dict over the network than to load the model state here, serialize it back to a state dict, then
      # load it back on the head node.
      return_value = (
          self.model
          if not return_state_dict
          else self.model.cpu().state_dict()
      )
  
      if self.skip_all_evaluation:
          self.close_writers(
              progress_tracker,
              save_path,
              train_summary_writer,
              validation_summary_writer,
              test_summary_writer,
          )
          return (
              return_value,
              progress_tracker.train_metrics,
              progress_tracker.validation_metrics,
              progress_tracker.test_metrics,
          )
  
      try:
          self.run_evaluation(
              training_set,
              validation_set,
              test_set,
              progress_tracker,
              train_summary_writer,
              validation_summary_writer,
              test_summary_writer,
              output_features,
              save_path,
          )
      finally:
          self.close_writers(
              progress_tracker,
              save_path,
              train_summary_writer,
              validation_summary_writer,
              test_summary_writer,
          )
  
      return (
          return_value,
          progress_tracker.train_metrics,
          progress_tracker.validation_metrics,
          progress_tracker.test_metrics,
      )
  
imports: import logging
  import os
  import time
  from typing import Callable, Dict, List, Optional, Union
  from torch.utils.tensorboard import SummaryWriter
  from ludwig.constants import MINIMUM_BATCH_SIZE, TEST, TRAINING, VALIDATION
  from ludwig.data.dataset.base import Dataset
  from ludwig.distributed.base import DistributedStrategy, LocalStrategy
  from ludwig.features.feature_utils import LudwigFeatureDict
  from ludwig.models.llm import LLM
  from ludwig.models.predictor import LlmFineTunePredictor, LlmPredictor
  from ludwig.modules.metric_modules import get_initial_validation_value
  from ludwig.schema.trainer import BaseTrainerConfig, FineTuneTrainerConfig, NoneTrainerConfig
  from ludwig.trainers.base import BaseTrainer
  from ludwig.trainers.registry import register_llm_ray_trainer, register_llm_trainer
  from ludwig.trainers.trainer import Trainer
  from ludwig.types import ModelConfigDict
  from ludwig.utils import time_utils
  from ludwig.utils.defaults import default_random_seed
  from ludwig.utils.metric_utils import TrainerMetric
  from ludwig.utils.metrics_printed_table import print_metrics_table
  from ludwig.utils.misc_utils import set_random_seed
  from ludwig.utils.torch_utils import get_torch_device
  from ludwig.utils.trainer_utils import append_metrics, get_new_progress_tracker, ProgressTracker
label_desc: Use image node_id 3 for calling the NoneTrainer obj's underlying member method code with example usage: obj.train(training_set, validation_set, test_set, save_path, return_state_dict) and returns: return_value,  progress_tracker,  progress_tracker,  progress_tracker, return_value,  progress_tracker,  progress_tracker,  progress_tracker