code: def run_sanity_checks(
      nemo_file, mcore_file, cpu_only=False, ignore_if_missing=tuple()
  ):
      nemo_model = restore_model(nemo_file, cpu_only=cpu_only).eval()
      mcore_model = restore_model(mcore_file, cpu_only=cpu_only).eval()
  
      logging.debug("*** Mcore model restored config")
      logging.debug(OmegaConf.to_yaml(mcore_model.cfg))
  
      nemo_summary = nemo_model.summarize()
      mcore_summary = mcore_model.summarize()
  
      logging.info("Sanity checks:")
  
      # check num weights match
      assert (
          nemo_summary.total_parameters
          == mcore_summary.total_parameters
      ), "❌ total parameters do not match"
      assert (
          nemo_summary.model_size == mcore_summary.model_size
      ), "❌ model sizes do not match"
      logging.info("✅ Number of weights match")
  
      # check weights match
      mcore_state_dict = mcore_model.state_dict()
      nemo_state_dict = nemo_model.state_dict()
      with open_dict(nemo_model.cfg):
          nemo_model.cfg.megatron_amp_O2 = False  # we want build_key_mapping in the next line to not use O2 prefix
      for mcore_param, nemo_param in build_key_mapping(
          nemo_model.cfg
      ).items():
          try:
              mcore_weight = mcore_state_dict.pop(mcore_param)
              nemo_weight = nemo_state_dict.pop(nemo_param)
              if mcore_param.endswith("linear_fc1.weight"):
                  # linear_fc1.weight should map to concat(dense_h_to_4h.weight, dense_h_to_4h_2.weight)
                  # but build_key_mapping only maps it to dense_h_to_4h.weight, so we handle the concat here.
                  second_param = nemo_param.replace(
                      "dense_h_to_4h.weight", "dense_h_to_4h_2.weight"
                  )
                  if second_param in nemo_state_dict:
                      nemo_weight = torch.cat(
                          [
                              nemo_weight,
                              nemo_state_dict.pop(second_param),
                          ]
                      )
              assert torch.allclose(
                  mcore_weight, nemo_weight
              ), f"❌ parameter {mcore_param} does not match"
          except KeyError:
              buffers = [k for k, v in mcore_model.named_buffers()]
              assert (
                  mcore_param in buffers
                  or mcore_param.replace("model.", "model.module.", 1)
                  in buffers
                  or any(
                      mcore_param.endswith(suffix)
                      for suffix in ignore_if_missing
                  )
              ), f"❌ parameter {mcore_param} is not found in the state dict or named_buffers()"
              nemo_state_dict.pop(nemo_param)
  
      logging.info("✅ Weights match")
  
      # check for unexpected weights in state dict
      assert (
          len(nemo_state_dict) == 0
      ), f"❌ unexpected items in nemo_state_dict: {nemo_state_dict}"
      assert (
          len(
              [
                  k
                  for k in mcore_state_dict
                  if not k.endswith("_extra_state")
              ]
          )
          == 0
      ), f"❌ unexpected items in mcore_state_dict: {mcore_state_dict}"
      logging.info("✅ No unexpected weights in state dicts")
  
file_path: NeMo/scripts/nlp_language_modeling/convert_nemo_gpt_to_mcore.py
imports: import os
  from argparse import ArgumentParser
  from collections import OrderedDict
  import torch
  from omegaconf import OmegaConf, open_dict
  from pytorch_lightning.trainer.trainer import Trainer
  from nemo.collections.nlp.models.language_modeling.megatron_gpt_model import MegatronGPTModel
  from nemo.collections.nlp.parts.nlp_overrides import NLPDDPStrategy
  from nemo.utils import AppState, logging
label_desc: Use image node_id 8 for calling a global function with example usage: run_sanity_checks(nemo_file, mcore_file, cpu_only, ignore_if_missing) without return types