How to get onnx format from pretrained GPT2 models?

Viewed 504

I'm trying to transform KoGPT2 model, which is pretrained by GPT2, to onnx format in order to change the model to tensorflow format.

I used convert_graph_to_onnx in transformers but it didn't work because of some reasons.

I don't know what this error implied. Is it possible to make onnx format with this model? Here is the code I implemented and last one is the error.

Thanks.

import sys
!{sys.executable} -m pip install --upgrade git+https://github.com/huggingface/transformers
!{sys.executable} -m pip install --upgrade torch==1.6.0+cpu torchvision==0.7.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
!{sys.executable} -m pip install --upgrade onnxruntime==1.4.0
!{sys.executable} -m pip install -i https://test.pypi.org/simple/ ort-nightly
!{sys.executable} -m pip install --upgrade onnxruntime-tools
!rm -rf onnx/
from pathlib import Path
from transformers.convert_graph_to_onnx import convert

# Handles all the above steps for you
convert(framework="pt", model="skt/kogpt2-base-v2", output=Path('/content/drive/MyDrive/kogptonnx/kogpt.onnx'), opset=12)

# Tensorflow 
# convert(framework="tf", model="bert-base-cased", output="onnx/bert-base-cased.onnx", opset=11)
ONNX opset version set to: 11
Loading pipeline (model: skt/kogpt2-base-v2, tokenizer: skt/kogpt2-base-v2)
Some weights of the model checkpoint at skt/kogpt2-base-v2 were not used when initializing GPT2Model: ['lm_head.weight']
- This IS expected if you are initializing GPT2Model from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).
- This IS NOT expected if you are initializing GPT2Model from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
Using framework PyTorch: 1.6.0+cpu
Found input input_ids with shape: {0: 'batch', 1: 'sequence'}
Found input attention_mask with shape: {0: 'batch', 1: 'sequence'}
Found output output_0 with shape: {0: 'batch', 1: 'sequence'}
Found output output_1 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_1 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_2 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_2 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_3 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_3 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_4 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_4 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_5 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_5 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_6 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_6 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_7 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_7 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_8 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_8 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_9 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_9 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_10 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_10 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_11 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_11 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_12 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Found output output_12 with shape: {0: 'batch', 1: 'sequence', 2: 'sequence'}
Ensuring inputs are in correct order
past_key_values is not present in the generated input list.
Generated inputs order: ['input_ids']
/usr/local/lib/python3.7/dist-packages/transformers/models/gpt2/modeling_gpt2.py:181: TracerWarning: Converting a tensor to a Python float might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!
  attn_weights = attn_weights / (float(value.size(-1)) ** 0.5)
/usr/local/lib/python3.7/dist-packages/transformers/models/gpt2/modeling_gpt2.py:186: TracerWarning: Converting a tensor to a Python index might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!
  causal_mask = self.bias[:, :, key_length - query_length : key_length, :key_length].bool()
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-6-78cc7242cbdd> in <module>()
      4 
      5 # Handles all the above steps for you
----> 6 convert(framework="pt", model="skt/kogpt2-base-v2", output=Path('/content/drive/MyDrive/kogptonnx/kogpt.onnx'), opset=11)
      7 
      8 # Tensorflow

6 frames
/usr/local/lib/python3.7/dist-packages/torch/onnx/utils.py in _optimize_graph(graph, operator_export_type, _disable_torch_constant_prop, fixed_batch_size, params_dict)
    187 
    188         graph = torch._C._jit_pass_onnx(graph, operator_export_type)
--> 189         torch._C._jit_pass_lint(graph)
    190 
    191         torch._C._jit_pass_onnx_scalar_type_analysis(graph)

RuntimeError: Unable to cast from non-held to held instance (T& to Holder<T>) (compile in debug mode for type information)
1 Answers

Not sure if it will help here, but I had the same Unable to cast from non-held to held instance error message for a different model (but also a transformer), and in my case adding the operator_export_type=torch.onnx.OperatorExportTypes.ONNX_ATEN_FALLBACK option to torch.onnx.export(...) (as mentioned here) fixed it for me:

torch.onnx.export(model, input, "output-name.onnx", export_params=True, opset_version=12, operator_export_type=torch.onnx.OperatorExportTypes.ONNX_ATEN_FALLBACK)
Related