code: def parse_log_history(log_history):
      """
      Parse the `log_history` of a Trainer to get the intermediate and final evaluation results.
      """
      idx = 0
      while (
          idx < len(log_history)
          and "train_runtime" not in log_history[idx]
      ):
          idx += 1
  
      # If there are no training logs
      if idx == len(log_history):
          idx -= 1
          while idx >= 0 and "eval_loss" not in log_history[idx]:
              idx -= 1
  
          if idx >= 0:
              return None, None, log_history[idx]
          else:
              return None, None, None
  
      # From now one we can assume we have training logs:
      train_log = log_history[idx]
      lines = []
      training_loss = "No log"
      for i in range(idx):
          if "loss" in log_history[i]:
              training_loss = log_history[i]["loss"]
          if "eval_loss" in log_history[i]:
              metrics = log_history[i].copy()
              _ = metrics.pop("total_flos", None)
              epoch = metrics.pop("epoch", None)
              step = metrics.pop("step", None)
              _ = metrics.pop("eval_runtime", None)
              _ = metrics.pop("eval_samples_per_second", None)
              _ = metrics.pop("eval_steps_per_second", None)
              values = {
                  "Training Loss": training_loss,
                  "Epoch": epoch,
                  "Step": step,
              }
              for k, v in metrics.items():
                  if k == "eval_loss":
                      values["Validation Loss"] = v
                  else:
                      splits = k.split("_")
                      name = " ".join(
                          [part.capitalize() for part in splits[1:]]
                      )
                      values[name] = v
              lines.append(values)
  
      idx = len(log_history) - 1
      while idx >= 0 and "eval_loss" not in log_history[idx]:
          idx -= 1
  
      if idx > 0:
          eval_results = {}
          for key, value in log_history[idx].items():
              if key.startswith("eval_"):
                  key = key[5:]
              if key not in [
                  "runtime",
                  "samples_per_second",
                  "steps_per_second",
                  "epoch",
                  "step",
              ]:
                  camel_cased_key = " ".join(
                      [part.capitalize() for part in key.split("_")]
                  )
                  eval_results[camel_cased_key] = value
          return train_log, lines, eval_results
      else:
          return train_log, lines, None
  
imports: import copy
  import json
  import os
  import warnings
  from dataclasses import dataclass
  from pathlib import Path
  from typing import Any, Dict, List, Optional, Union
  import requests
  import yaml
  from huggingface_hub import model_info
  from huggingface_hub.utils import HFValidationError
  from .None import __version__
  from .models.auto.modeling_auto import MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES, MODEL_FOR_CAUSAL_LM_MAPPING_NAMES, MODEL_FOR_CTC_MAPPING_NAMES, MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES, MODEL_FOR_IMAGE_SEGMENTATION_MAPPING_NAMES, MODEL_FOR_MASKED_LM_MAPPING_NAMES, MODEL_FOR_OBJECT_DETECTION_MAPPING_NAMES, MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES, MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES, MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES, MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES, MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES, MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES
  from .training_args import ParallelMode
  from .utils import MODEL_CARD_NAME, cached_file, is_datasets_available, is_offline_mode, is_tf_available, is_tokenizers_available, is_torch_available, logging
label_desc: Use image node_id 8 for calling a global function with example usage: parse_log_history(log_history) and returns: train_log,  lines,  eval_results, train_log,  lines,  None, None,  None,  log_history, None,  None,  None