code: def run_inference(cfg: InferenceConfig) -> InferenceConfig:
      logging.info(f"Hydra config: {OmegaConf.to_yaml(cfg)}")
  
      if is_dataclass(cfg):
          cfg = OmegaConf.structured(cfg)
  
      if cfg.model_path is None and cfg.pretrained_name is None:
          raise ValueError(
              "Both cfg.model_path and cfg.pretrained_name cannot be None!"
          )
      if cfg.audio_dir is None and cfg.dataset_manifest is None:
          raise ValueError(
              "Both cfg.audio_dir and cfg.dataset_manifest cannot be None!"
          )
  
      # setup GPU
      if cfg.cuda is None:
          if torch.cuda.is_available():
              device = [0]  # use 0th CUDA device
              accelerator = "gpu"
          else:
              device = 1
              accelerator = "cpu"
      else:
          device = [cfg.cuda]
          accelerator = "gpu"
  
      map_location = torch.device(
          "cuda:{}".format(device[0]) if accelerator == "gpu" else "cpu"
      )
  
      # setup model
      if cfg.model_path is not None:
          # restore model from .nemo file path
          logging.info(f"Restoring model : {cfg.model_path}")
          model = SLUIntentSlotBPEModel.restore_from(
              restore_path=cfg.model_path, map_location=map_location
          )
          model_name = os.path.splitext(
              os.path.basename(cfg.model_path)
          )[0]
      else:
          # restore model by name
          model = SLUIntentSlotBPEModel.from_pretrained(
              model_name=cfg.pretrained_name, map_location=map_location
          )
          model_name = cfg.pretrained_name
  
      trainer = pl.Trainer(devices=device, accelerator=accelerator)
      model.set_trainer(trainer)
      model = model.eval()
  
      # Setup decoding strategy
      model.set_decoding_strategy(cfg.sequence_generator)
  
      # get audio filenames
      if cfg.audio_dir is not None:
          filepaths = list(
              glob.glob(
                  os.path.join(cfg.audio_dir, f"**/*.{cfg.audio_type}"),
                  recursive=True,
              )
          )
      else:
          # get filenames from manifest
          filepaths = []
          if os.stat(cfg.dataset_manifest).st_size == 0:
              logging.error(
                  f"The input dataset_manifest {cfg.dataset_manifest} is empty. Exiting!"
              )
              return None
  
          manifest_dir = Path(cfg.dataset_manifest).parent
          with open(cfg.dataset_manifest, "r") as f:
              has_two_fields = []
              for line in f:
                  item = json.loads(line)
                  if "offset" in item and "duration" in item:
                      has_two_fields.append(True)
                  else:
                      has_two_fields.append(False)
                  audio_file = Path(item["audio_filepath"])
                  if (
                      not audio_file.is_file()
                      and not audio_file.is_absolute()
                  ):
                      audio_file = manifest_dir / audio_file
                  filepaths.append(str(audio_file.absolute()))
  
      logging.info(
          f"\nStart inference with {len(filepaths)} files...\n"
      )
  
      # setup AMP (optional)
      if (
          cfg.amp
          and torch.cuda.is_available()
          and hasattr(torch.cuda, "amp")
          and hasattr(torch.cuda.amp, "autocast")
      ):
          logging.info("AMP enabled!\n")
          autocast = torch.cuda.amp.autocast
      else:
  
          @contextlib.contextmanager
          def autocast():
              yield
  
      # Compute output filename
      if cfg.output_filename is None:
          # create default output filename
          if cfg.audio_dir is not None:
              cfg.output_filename = (
                  os.path.dirname(os.path.join(cfg.audio_dir, "."))
                  + ".json"
              )
          else:
              cfg.output_filename = cfg.dataset_manifest.replace(
                  ".json", f"_{model_name}.json"
              )
  
      # if transcripts should not be overwritten, and already exists, skip re-transcription step and return
      if not cfg.overwrite_transcripts and os.path.exists(
          cfg.output_filename
      ):
          logging.info(
              f"Previous transcripts found at {cfg.output_filename}, and flag `overwrite_transcripts`"
              f"is {cfg.overwrite_transcripts}. Returning without re-transcribing text."
          )
  
          return cfg
  
      # transcribe audio
      with autocast():
          with torch.no_grad():
              predictions = slurp_inference(
                  model=model,
                  path2manifest=cfg.dataset_manifest,
                  batch_size=cfg.batch_size,
                  num_workers=cfg.num_workers,
              )
  
      logging.info(f"Finished transcribing {len(filepaths)} files !")
  
      logging.info(
          f"Writing transcriptions into file: {cfg.output_filename}"
      )
  
      # write audio transcriptions
      with open(cfg.output_filename, "w", encoding="utf-8") as f:
          if cfg.audio_dir is not None:
              for idx, text in enumerate(predictions):
                  item = {
                      "audio_filepath": filepaths[idx],
                      "pred_text": text,
                  }
                  f.write(json.dumps(item) + "\n")
          else:
              with open(cfg.dataset_manifest, "r") as fr:
                  for idx, line in enumerate(fr):
                      item = json.loads(line)
                      item["pred_text"] = predictions[idx]
                      f.write(json.dumps(item) + "\n")
  
      logging.info("Finished writing predictions !")
      return cfg
  
file_path: NeMo/examples/slu/speech_intent_slot/eval_utils/inference.py
imports: import contextlib
  import glob
  import json
  import os
  from dataclasses import dataclass, is_dataclass
  from pathlib import Path
  from typing import List, Optional
  import pytorch_lightning
  import torch
  from omegaconf import OmegaConf
  from tqdm.auto import tqdm
  from nemo.collections.asr.models import SLUIntentSlotBPEModel
  from nemo.collections.asr.parts.utils.slu_utils import SequenceGeneratorConfig
  from nemo.core.config import hydra_runner
  from nemo.utils import logging
label_desc: Use image node_id 2 for calling a global function with example usage: run_inference(cfg) and returns: cfg, cfg, None