code: def run_asr_inference(manifest_filepath, cfg, record_fn) -> str:
      logging.info("Start ASR inference pipeline...")
      asr_model = init_asr_model(cfg.asr_model)
      device = torch.device(
          "cuda" if torch.cuda.is_available() else "cpu"
      )
      asr_model = asr_model.to(device)
      asr_model.eval()
  
      # Setup decoding strategy
      decode_function = None
      decoder_type = cfg.get("decoder_type", None)
      if not hasattr(asr_model, "change_decoding_strategy"):
          raise ValueError(
              f"ASR model {cfg.asr_model} does not support decoding strategy."
          )
      if decoder_type is not None:  # Hybrid model
          if decoder_type == "rnnt":
              cfg.rnnt_decoding.fused_batch_size = -1
              cfg.rnnt_decoding.compute_langs = cfg.compute_langs
              asr_model.change_decoding_strategy(
                  cfg.rnnt_decoding, decoder_type=decoder_type
              )
              decode_function = (
                  asr_model.decoding.rnnt_decoder_predictions_tensor
              )
          elif decoder_type == "ctc":
              asr_model.change_decoding_strategy(
                  cfg.ctc_decoding, decoder_type=decoder_type
              )
              decode_function = (
                  asr_model.decoding.ctc_decoder_predictions_tensor
              )
          else:
              raise ValueError(
                  f"Unknown decoder type for hybrid model: {decoder_type}, supported types: ['rnnt', 'ctc']"
              )
      elif hasattr(asr_model, "joint"):  # RNNT model
          cfg.rnnt_decoding.fused_batch_size = -1
          cfg.rnnt_decoding.compute_langs = cfg.compute_langs
          asr_model.change_decoding_strategy(cfg.rnnt_decoding)
          decode_function = (
              asr_model.decoding.rnnt_decoder_predictions_tensor
          )
      else:
          asr_model.change_decoding_strategy(cfg.ctc_decoding)
          decode_function = (
              asr_model.decoding.ctc_decoder_predictions_tensor
          )
  
      # Compute output filename
      if cfg.output_filename is None:
          # create default output filename
          if cfg.pred_name_postfix is not None:
              cfg.output_filename = cfg.manifest_filepath.replace(
                  ".json", f"_{cfg.pred_name_postfix}.json"
              )
          else:
              tag = f"{cfg.normalize}_{cfg.normalize_type}"
              if cfg.use_rttm:
                  vad_tag = Path(manifest_filepath).stem
                  vad_tag = vad_tag[len("temp_manifest_vad_rttm_") :]
                  if cfg.rttm_mode == "mask":
                      tag += f"-mask{cfg.feat_mask_val}-{vad_tag}"
                  else:
                      tag += f"-dropframe-{vad_tag}"
              cfg.output_filename = cfg.manifest_filepath.replace(
                  ".json", f"-{Path(cfg.asr_model).stem}-{tag}.json"
              )
          cfg.output_filename = (
              Path(cfg.output_dir) / Path(cfg.output_filename).name
          )
  
      logging.info("Setting up dataloader for ASR...")
      data_config = {
          "manifest_filepath": manifest_filepath,
          "normalize": cfg.normalize,
          "normalize_type": cfg.normalize_type,
          "use_rttm": cfg.use_rttm,
          "rttm_mode": cfg.rttm_mode,
          "feat_mask_val": cfg.feat_mask_val,
          "frame_unit_time_secs": cfg.frame_unit_time_secs,
      }
      logging.info(
          f"use_rttm = {cfg.use_rttm}, rttm_mode = {cfg.rttm_mode}, feat_mask_val = {cfg.feat_mask_val}"
      )
  
      if hasattr(asr_model, "tokenizer"):
          dataset = feature_to_text_dataset.get_bpe_dataset(
              config=data_config, tokenizer=asr_model.tokenizer
          )
      else:
          data_config["labels"] = asr_model.decoder.vocabulary
          dataset = feature_to_text_dataset.get_char_dataset(
              config=data_config
          )
  
      dataloader = torch.utils.data.DataLoader(
          dataset=dataset,
          batch_size=cfg.batch_size,
          collate_fn=dataset._collate_fn,
          drop_last=False,
          shuffle=False,
          num_workers=cfg.get("num_workers", 0),
          pin_memory=cfg.get("pin_memory", False),
      )
  
      logging.info("Start transcribing...")
      hypotheses = []
      all_hypotheses = []
      t0 = time.time()
      with autocast():
          with torch.no_grad():
              with record_fn("asr_infer_loop"):
                  for test_batch in tqdm(
                      dataloader, desc="Transcribing"
                  ):
                      with record_fn("asr_infer_model"):
                          outputs = asr_model.forward(
                              processed_signal=test_batch[0].to(device),
                              processed_signal_length=test_batch[1].to(
                                  device
                              ),
                          )
  
                      with record_fn("asr_infer_other"):
                          logits, logits_len = outputs[0], outputs[1]
  
                          current_hypotheses, all_hyp = decode_function(
                              logits,
                              logits_len,
                              return_hypotheses=False,
                          )
                          if (
                              isinstance(current_hypotheses, tuple)
                              and len(current_hypotheses) == 2
                          ):
                              current_hypotheses = current_hypotheses[
                                  0
                              ]  # handle RNNT output
  
                          hypotheses += current_hypotheses
                          if all_hyp is not None:
                              all_hypotheses += all_hyp
                          else:
                              all_hypotheses += current_hypotheses
  
                          del logits
                          del test_batch
      t1 = time.time()
      logging.info(f"Time elapsed: {t1 - t0: .2f} seconds")
  
      logging.info("Finished transcribing.")
      # Save output to manifest
      input_manifest_data = read_manifest(manifest_filepath)
      manifest_data = read_manifest(cfg.manifest_filepath)
  
      if "text" not in manifest_data[0]:
          has_groundtruth = False
      else:
          has_groundtruth = True
  
      groundtruth = []
      for i in range(len(manifest_data)):
          if has_groundtruth:
              groundtruth.append(manifest_data[i]["text"])
          manifest_data[i]["pred_text"] = hypotheses[i]
          manifest_data[i]["feature_file"] = input_manifest_data[i][
              "feature_file"
          ]
          if "rttm_file" in input_manifest_data[i]:
              manifest_data[i]["feature_file"] = input_manifest_data[i][
                  "feature_file"
              ]
  
      write_manifest(cfg.output_filename, manifest_data)
  
      if not has_groundtruth:
          hypotheses = " ".join(hypotheses)
          words = hypotheses.split()
          chars = "".join(words)
          logging.info("-----------------------------------------")
          logging.info(f"Number of generated characters={len(chars)}")
          logging.info(f"Number of generated words={len(words)}")
          logging.info("-----------------------------------------")
      else:
          wer_score = word_error_rate(
              hypotheses=hypotheses, references=groundtruth
          )
          cer_score = word_error_rate(
              hypotheses=hypotheses,
              references=groundtruth,
              use_cer=True,
          )
          logging.info("-----------------------------------------")
          logging.info(f"WER={wer_score:.4f}, CER={cer_score:.4f}")
          logging.info("-----------------------------------------")
  
      logging.info(f"ASR output saved at {cfg.output_filename}")
      return cfg.output_filename
  
imports: import contextlib
  import json
  import os
  import time
  from dataclasses import dataclass, is_dataclass
  from pathlib import Path
  from typing import Callable, Optional
  import torch
  import yaml
  from omegaconf import DictConfig, OmegaConf
  from torch.profiler import ProfilerActivity, profile, record_function
  from tqdm import tqdm
  from nemo.collections.asr.data import feature_to_text_dataset
  from nemo.collections.asr.metrics.wer import word_error_rate
  from nemo.collections.asr.models import ASRModel, EncDecClassificationModel
  from nemo.collections.asr.parts.submodules import CTCDecodingConfig
  from nemo.collections.asr.parts.submodules.rnnt_decoding import RNNTDecodingConfig
  from nemo.collections.asr.parts.utils.manifest_utils import read_manifest, write_manifest
  from nemo.collections.asr.parts.utils.vad_utils import generate_overlap_vad_seq, generate_vad_segment_table, get_vad_stream_status, init_frame_vad_model, init_vad_model
  from nemo.core.config import hydra_runner
  from nemo.utils import logging
label_desc: Use image node_id 7 for calling a global function with example usage: run_asr_inference(manifest_filepath, cfg, record_fn) and returns: cfg