class_docstr: TrainLoop contains the core training loop logic.
class_docstr_tok: ["TrainLoop","contains","the","core","training","loop","logic","."]
docstr: Compute the estimated seconds remaining in training.
  
  :param float epochs_completed: number of epochs already completed.
  :param float time_elapsed: total time spent already, in seconds.
  :return: ETA in seconds, or None if not computable
docstr_tok: ["Compute","the","estimated","seconds","remaining","in","training",".",":","param","float","epochs_completed",":","number","of","epochs","already","completed",".",":","param","float","time_elapsed",":","total","time","spent","already",",","in","seconds",".",":","return",":","ETA","in","seconds",",","or","None","if","not","computable"]
code: def _compute_eta(
      self,
      epochs_completed: float,
      time_elapsed: float,
      steps_taken: int,
  ):
      """
      Compute the estimated seconds remaining in training.
  
      :param float epochs_completed: number of epochs already completed.
      :param float time_elapsed: total time spent already, in seconds.
      :return: ETA in seconds, or None if not computable
      """
      # start off with no estimate
      eta = None
  
      # Determine time_left and num_epochs
      max_epochs = self.opt.get("num_epochs", 0)
      if max_epochs > 0 and epochs_completed > 0:
          epoch_progress = epochs_completed / max_epochs
          eta = (1 - epoch_progress) * time_elapsed / epoch_progress
  
      max_training_time = self.opt.get("max_training_time", -1)
      if max_training_time > 0:
          time_left = max_training_time - time_elapsed
          if eta is None or time_left < eta:
              eta = time_left
  
      max_train_steps = self.opt.get("max_train_steps", -1)
      if max_train_steps > 0 and steps_taken > 0:
          steps_progress = steps_taken / max_train_steps
          eta = (1 - steps_progress) * time_elapsed / steps_progress
  
      return eta
  
imports: import copy
  import random
  import torch
  import json
  import os
  import signal
  from typing import Tuple
  import numpy
  import parlai.utils.logging
  from parlai.core.agents import create_agent, create_agent_from_shared
  from parlai.core.exceptions import StopTrainException
  from parlai.core.logs import TensorboardLogger, WandbLogger, ClearMLLogger
  from parlai.core.metrics import Metric
  from parlai.core.metrics import aggregate_named_reports, aggregate_unnamed_reports, dict_report
  from parlai.core.opt import Opt
  from parlai.core.params import ParlaiParser, print_announcements
  from parlai.core.script import ParlaiScript, register_script
  from parlai.core.worlds import create_task, World
  from parlai.scripts.build_dict import build_dict, setup_args
  from parlai.scripts.eval_model import get_task_world_logs
  from parlai.utils.distributed import sync_object, is_primary_worker, all_gather_list, is_distributed, get_rank, num_workers
  from parlai.utils.io import PathManager
  from parlai.utils.misc import Timer, nice_report
  from parlai.utils.world_logging import WorldLogger
label_desc: Use image node_id 9 for calling the TrainLoop obj's underlying member method code with example usage: obj._compute_eta(epochs_completed, time_elapsed, steps_taken) and returns: eta