code: def final_save(model, save_dir, tokenizer, cfg):
      if not os.path.exists(save_dir):
          os.makedirs(save_dir)
      with open(os.path.join(save_dir, "model.yml"), "w") as of:
          of.write(cfg.dump())
      tokenizer.vocab.save(os.path.join(save_dir, "vocab.json"))
      model.backbone_model.save_parameters(
          os.path.join(save_dir, "model.params")
      )
      logging.info("Statistics:")
      old_names = os.listdir(save_dir)
      for old_name in old_names:
          new_name, long_hash = naming_convention(save_dir, old_name)
          old_path = os.path.join(save_dir, old_name)
          new_path = os.path.join(save_dir, new_name)
          shutil.move(old_path, new_path)
          file_size = os.path.getsize(new_path)
          logging.info(
              "\t{}/{} {} {}".format(
                  save_dir, new_name, long_hash, file_size
              )
          )
  
file_path: gluon-nlp/scripts/pretraining/bert/run_pretraining.py
imports: import os
  import time
  import shutil
  import logging
  import argparse
  import functools
  import collections
  import mxnet
  import numpy
  from pretraining_utils import get_pretrain_data_npz, get_pretrain_data_text, MaskedAccuracy
  from gluonnlp.utils.misc import repeat, grouper, set_seed, init_comm, logging_config, naming_convention
  from gluonnlp.initializer import TruncNorm
  from gluonnlp.models.bert import BertModel, BertForPretrain, get_pretrained_bert
  from gluonnlp.utils.parameter import clip_grad_global_norm
label_desc: Use image node_id 3 for calling a global function with example usage: final_save(model, save_dir, tokenizer, cfg) without return types