code: def main():
      # We now keep distinct sets of args, for a cleaner separation of concerns.
      parser = HfArgumentParser(
          (
              ModelArguments,
              DataTrainingArguments,
              TrainingArguments,
              OptimizationArguments,
              OnnxExportArguments,
          )
      )
      if len(sys.argv) == 2 and sys.argv[1].endswith(".json"):
          # If we pass only one argument to the script and it's the path to a json file,
          # let's parse it to get our arguments.
          (
              model_args,
              data_args,
              training_args,
              optim_args,
              onnx_export_args,
          ) = parser.parse_json_file(
              json_file=os.path.abspath(sys.argv[1])
          )
      else:
          (
              model_args,
              data_args,
              training_args,
              optim_args,
              onnx_export_args,
          ) = parser.parse_args_into_dataclasses()
  
      # Setup logging
      logging.basicConfig(
          format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
          datefmt="%m/%d/%Y %H:%M:%S",
          handlers=[logging.StreamHandler(sys.stdout)],
      )
      log_level = training_args.get_process_log_level()
      logger.setLevel(log_level)
      datasets.utils.logging.set_verbosity(log_level)
      transformers.utils.logging.set_verbosity(log_level)
      transformers.utils.logging.enable_default_handler()
      transformers.utils.logging.enable_explicit_format()
  
      if (
          optim_args.optimization_level > 1
          and optim_args.optimize_for_gpu
          and model_args.execution_provider == "CPUExecutionProvider"
      ):
          raise ValueError(
              f"Optimization level is set at {optim_args.optimization_level} and "
              f"GPU optimization will be done, although the CPU execution provider "
              f"was selected. Use --execution_provider CUDAExecutionProvider."
          )
  
      if (
          optim_args.optimization_level > 1
          and not optim_args.optimize_for_gpu
          and model_args.execution_provider == "CUDAExecutionProvider"
      ):
          raise ValueError(
              f"Optimization level is set at {optim_args.optimization_level} and "
              f"CPU optimization will be done, although the GPU execution provider "
              f"was selected. Remove the argument --execution_provider CUDAExecutionProvider."
          )
  
      logger.info(
          f"Optimization with the following parameters {optim_args}"
      )
  
      if (
          os.path.isdir(training_args.output_dir)
          and not training_args.overwrite_output_dir
      ):
          raise ValueError(
              f"Output directory ({training_args.output_dir}) already exists and is not empty. "
              "Use --overwrite_output_dir to overcome."
          )
  
      os.makedirs(training_args.output_dir, exist_ok=True)
      optimized_model_path = os.path.join(
          training_args.output_dir, "model_optimized.onnx"
      )
  
      tokenizer = AutoTokenizer.from_pretrained(
          model_args.tokenizer_name or model_args.model_name_or_path
      )
  
      # Create the optimization configuration containing all the optimization parameters
      optimization_config = OptimizationConfig(
          optimization_level=optim_args.optimization_level,
          optimize_with_onnxruntime_only=optim_args.optimize_with_onnxruntime_only,
          optimize_for_gpu=optim_args.optimize_for_gpu,
      )
  
      # Export the model
      model = ORTModelForMultipleChoice.from_pretrained(
          model_args.model_name_or_path, export=True
      )
  
      # Create the optimizer
      optimizer = ORTOptimizer.from_pretrained(model)
  
      # Optimize the model
      optimizer.optimize(
          optimization_config=optimization_config,
          save_dir=training_args.output_dir,
          use_external_data_format=onnx_export_args.use_external_data_format,
          one_external_file=onnx_export_args.one_external_file,
      )
  
      if training_args.do_eval:
          # Prepare the dataset downloading, preprocessing and metric creation to perform the evaluation and / or the
          # prediction step(s)
          if (
              data_args.train_file is not None
              or data_args.validation_file is not None
          ):
              data_files = {}
              if data_args.train_file is not None:
                  data_files["train"] = data_args.train_file
              if data_args.validation_file is not None:
                  data_files["validation"] = data_args.validation_file
              extension = data_args.train_file.split(".")[-1]
              raw_datasets = load_dataset(
                  extension,
                  data_files=data_files,
                  cache_dir=model_args.cache_dir,
                  use_auth_token=True
                  if model_args.use_auth_token
                  else None,
              )
          else:
              # Downloading and loading the swag dataset from the hub.
              raw_datasets = load_dataset(
                  "swag",
                  "regular",
                  cache_dir=model_args.cache_dir,
                  use_auth_token=True
                  if model_args.use_auth_token
                  else None,
              )
  
          if "validation" not in raw_datasets:
              raise ValueError(
                  "--do_eval requires a validation dataset"
              )
          eval_dataset = raw_datasets["validation"]
          if data_args.max_eval_samples is not None:
              max_eval_samples = min(
                  len(eval_dataset), data_args.max_eval_samples
              )
              eval_dataset = eval_dataset.select(
                  range(max_eval_samples)
              )
  
          # When using your own dataset or a different dataset from swag, you will probably need to change this.
          ending_names = [f"ending{i}" for i in range(4)]
          context_name = "sent1"
          question_header_name = "sent2"
  
          # Preprocessing the datasets.
          def preprocess_function(
              examples, tokenizer: PreTrainedTokenizerBase
          ):
              first_sentences = [
                  [context] * 4 for context in examples[context_name]
              ]
              question_headers = examples[question_header_name]
              second_sentences = [
                  [
                      f"{header} {examples[end][i]}"
                      for end in ending_names
                  ]
                  for i, header in enumerate(question_headers)
              ]
  
              # Flatten out
              first_sentences = list(chain(*first_sentences))
              second_sentences = list(chain(*second_sentences))
  
              # Tokenize
              tokenized_examples = tokenizer(
                  first_sentences,
                  second_sentences,
                  truncation=True,
                  max_length=min(
                      data_args.max_seq_length,
                      tokenizer.model_max_length,
                  ),
                  padding="max_length",
              )
              # Un-flatten
              return {
                  k: [v[i : i + 4] for i in range(0, len(v), 4)]
                  for k, v in tokenized_examples.items()
              }
  
          # Preprocess the evaluation dataset
          with training_args.main_process_first(
              desc="Running tokenizer on the validation dataset"
          ):
              eval_dataset = eval_dataset.map(
                  partial(preprocess_function, tokenizer=tokenizer),
                  batched=True,
                  num_proc=data_args.preprocessing_num_workers,
                  load_from_cache_file=not data_args.overwrite_cache,
              )
  
          # Metric
          def compute_metrics(eval_predictions):
              predictions, label_ids = eval_predictions
              preds = np.argmax(predictions, axis=1)
              return {
                  "accuracy": (preds == label_ids)
                  .astype(np.float32)
                  .mean()
                  .item()
              }
  
          # Evaluation
          logger.info("*** Evaluate ***")
  
          ort_model = ORTModel(
              optimized_model_path,
              execution_provider=optim_args.execution_provider,
              compute_metrics=compute_metrics,
              label_names=["label"],
          )
          outputs = ort_model.evaluation_loop(eval_dataset)
  
          # Save evaluation metrics
          with open(
              os.path.join(
                  training_args.output_dir, "eval_results.json"
              ),
              "w",
          ) as f:
              json.dump(outputs.metrics, f, indent=4, sort_keys=True)
  
imports: import json
  import logging
  import os
  import sys
  from dataclasses import dataclass, field
  from functools import partial
  from itertools import chain
  from typing import Optional
  import datasets
  import numpy
  import transformers
  from datasets import load_dataset
  from transformers import AutoTokenizer, HfArgumentParser, TrainingArguments
  from transformers.tokenization_utils_base import PreTrainedTokenizerBase
  from transformers.utils import check_min_version
  from optimum.onnxruntime import ORTModelForMultipleChoice, ORTOptimizer
  from optimum.onnxruntime.configuration import OptimizationConfig
  from optimum.onnxruntime.model import ORTModel
label_desc: Use image node_id 1 for calling a global function with example usage: main() and returns: unknown, dict