code: def run_vad_inference(
      manifest_filepath: str, cfg: DictConfig, record_fn: Callable
  ) -> str:
      logging.info("Start VAD inference pipeline...")
      if cfg.vad_type == "segment":
          vad_model = init_vad_model(cfg.vad_model)
      elif cfg.vad_type == "frame":
          vad_model = init_frame_vad_model(cfg.vad_model)
      else:
          raise ValueError(
              f"Unknown VAD type: {cfg.vad_type}, supported types: ['segment', 'frame']"
          )
  
      device = torch.device(
          "cuda" if torch.cuda.is_available() else "cpu"
      )
      vad_model = vad_model.to(device)
      vad_model.eval()
  
      vad_yaml = Path(cfg.vad_config)
      if not vad_yaml.is_file():
          raise ValueError(
              f"VAD config file not found: {cfg.vad_config}"
          )
  
      with vad_yaml.open("r") as fp:
          vad_cfg = yaml.safe_load(fp)
      vad_cfg = DictConfig(vad_cfg)
  
      test_data_config = {
          "vad_stream": True,
          "manifest_filepath": manifest_filepath,
          "labels": [
              "infer",
          ],
          "num_workers": cfg.num_workers,
          "shuffle": False,
          "window_length_in_sec": vad_cfg.vad.parameters.window_length_in_sec,
          "shift_length_in_sec": vad_cfg.vad.parameters.shift_length_in_sec,
      }
      vad_model.setup_test_data(
          test_data_config=test_data_config, use_feat=True
      )
  
      pred_dir = Path(cfg.output_dir) / Path("vad_frame_pred")
      if pred_dir.is_dir():
          logging.info(
              f"VAD frame-level prediction already exists: {pred_dir}, skipped"
          )
      else:
          logging.info("Generating VAD frame-level prediction")
          pred_dir.mkdir(parents=True)
          t0 = time.time()
          pred_dir = generate_vad_frame_pred(
              vad_model=vad_model,
              window_length_in_sec=vad_cfg.vad.parameters.window_length_in_sec,
              shift_length_in_sec=vad_cfg.vad.parameters.shift_length_in_sec,
              manifest_vad_input=manifest_filepath,
              out_dir=str(pred_dir),
              use_feat=True,
              record_fn=record_fn,
          )
          t1 = time.time()
          logging.info(f"Time elapsed: {t1 - t0: .2f} seconds")
          logging.info(
              f"Finished generating VAD frame level prediction with window_length_in_sec={vad_cfg.vad.parameters.window_length_in_sec} and shift_length_in_sec={vad_cfg.vad.parameters.shift_length_in_sec}"
          )
  
      frame_length_in_sec = vad_cfg.vad.parameters.shift_length_in_sec
      # overlap smoothing filter
      if vad_cfg.vad.parameters.smoothing:
          # Generate predictions with overlapping input segments. Then a smoothing filter is applied to decide the label for a frame spanned by multiple segments.
          # smoothing_method would be either in majority vote (median) or average (mean)
          logging.info(
              "Generating predictions with overlapping input segments"
          )
          t0 = time.time()
          smoothing_pred_dir = generate_overlap_vad_seq(
              frame_pred_dir=pred_dir,
              smoothing_method=vad_cfg.vad.parameters.smoothing,
              overlap=vad_cfg.vad.parameters.overlap,
              window_length_in_sec=vad_cfg.vad.parameters.window_length_in_sec,
              shift_length_in_sec=vad_cfg.vad.parameters.shift_length_in_sec,
              num_workers=cfg.num_workers,
              out_dir=vad_cfg.smoothing_out_dir,
          )
          logging.info(
              f"Finish generating predictions with overlapping input segments with smoothing_method={vad_cfg.vad.parameters.smoothing} and overlap={vad_cfg.vad.parameters.overlap}"
          )
          t1 = time.time()
          logging.info(f"Time elapsed: {t1 - t0: .2f} seconds")
          pred_dir = smoothing_pred_dir
          frame_length_in_sec = 0.01
  
      # Turn frame-wise prediction into speech intervals
      logging.info(
          f"Generating segment tables with postprocessing params: {vad_cfg.vad.parameters.postprocessing}"
      )
      segment_dir_name = "vad_rttm"
      for key, val in vad_cfg.vad.parameters.postprocessing.items():
          segment_dir_name = (
              segment_dir_name + "-" + str(key) + str(val)
          )
  
      segment_dir = Path(cfg.output_dir) / Path(segment_dir_name)
      if segment_dir.is_dir():
          logging.info(
              f"VAD speech segments already exists: {segment_dir}, skipped"
          )
      else:
          segment_dir.mkdir(parents=True)
          t0 = time.time()
          segment_dir = generate_vad_segment_table(
              vad_pred_dir=pred_dir,
              postprocessing_params=vad_cfg.vad.parameters.postprocessing,
              frame_length_in_sec=frame_length_in_sec,
              num_workers=cfg.num_workers,
              out_dir=segment_dir,
              use_rttm=True,
          )
          t1 = time.time()
          logging.info(f"Time elapsed: {t1 - t0: .2f} seconds")
          logging.info(
              "Finished generating RTTM files from VAD predictions."
          )
  
      rttm_map = {}
      for filepath in Path(segment_dir).glob("*.rttm"):
          rttm_map[filepath.stem] = str(filepath.absolute())
  
      manifest_data = read_manifest(manifest_filepath)
      for i in range(len(manifest_data)):
          key = Path(manifest_data[i]["audio_filepath"]).stem
          manifest_data[i]["rttm_file"] = rttm_map[key]
  
      new_manifest_filepath = str(
          Path(cfg.output_dir)
          / Path(f"temp_manifest_{segment_dir_name}.json")
      )
      write_manifest(new_manifest_filepath, manifest_data)
      return new_manifest_filepath
  
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 4 for calling a global function with example usage: run_vad_inference(manifest_filepath, cfg, record_fn) and returns: new_manifest_filepath