class_docstr: TrainLoop contains the core training loop logic.
class_docstr_tok: ["TrainLoop","contains","the","core","training","loop","logic","."]
code: def _save_train_stats(self, suffix=None):
      if not is_primary_worker():
          # never do IO as a non-primary worker
          return
      fn = self.opt.get("model_file", None)
      if not fn:
          return
      if suffix:
          fn += suffix
      fn += ".trainstats"
      with PathManager.open(fn, "w") as f:
          json.dump(
              {
                  "parleys": self.parleys,
                  "train_time": self.train_time.time(),
                  "train_steps": self._train_steps,
                  "total_epochs": self._total_epochs,
                  "train_reports": self.train_reports,
                  "valid_reports": self.valid_reports,
                  "best_valid": self.best_valid,
                  "impatience": self.impatience,
                  "final_valid_report": dict_report(
                      self.final_valid_report
                  ),
                  "final_test_report": dict_report(
                      self.final_test_report
                  ),
                  "final_extra_valid_report": dict_report(
                      self.final_extra_valid_report
                  ),
              },
              f,
              indent=4,
          )
  
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 3 for calling the TrainLoop obj's underlying member method code with example usage: obj._save_train_stats(suffix) without return types