codingutf8 2018 the openai team s and huggingface inc team c 2018 nvidia corporation licensed under the apache license version 2 0 the license you may not use this file except in compliance with the license you may obtain a copy of the license at http www apache orglicenseslicense2 0 unless required by applicable law or agreed to in writing software distributed under the license is distributed on an as is basis without warranties or conditions of any kind either express or implied see the license for the specific language governing permissions and limitations under the license openai gpt2 configuration from collections import ordereddict from typing import any list mapping optional from import pretrainedtokenizer tensortype istorchavailable from configurationutils import pretrainedconfig from onnx import onnxconfigwithpast patchingspec from utils import logging logger logging getloggername gpt2pretrainedconfigarchivemap gpt2 https huggingface cogpt2resolvemainconfig json gpt2medium https huggingface cogpt2mediumresolvemainconfig json gpt2large https huggingface cogpt2largeresolvemainconfig json gpt2xl https huggingface cogpt2xlresolvemainconfig json distilgpt2 https huggingface codistilgpt2resolvemainconfig json class gpt2configpretrainedconfig todo how to do that better we need to order the input in the way they appears in the forward need to add the pastkeys not using the same length for pastkeyvalues coding utf 8 2018 the openai team s and huggingface inc team c 2018 nvidia corporation licensed under the apache license version 2 0 the license you may not use this file except in compliance with the license you may obtain a copy of the license at http www apache org licenses license 2 0 unless required by applicable law or agreed to in writing software distributed under the license is distributed on an as is basis without warranties or conditions of any kind either express or implied see the license for the specific language governing permissions and limitations under the license openai gpt 2 configuration this is the configuration class to store the configuration of a gpt2model or a tfgpt2model it is used to instantiate a gpt 2 model according to the specified arguments defining the model architecture instantiating a configuration with the defaults will yield a similar configuration to that of the gpt 2 gpt2 https huggingface co gpt2 architecture configuration objects inherit from pretrainedconfig and can be used to control the model outputs read the documentation from pretrainedconfig for more information args vocab_size int optional defaults to 50257 vocabulary size of the gpt 2 model defines the number of different tokens that can be represented by the inputs_ids passed when calling gpt2model or tfgpt2model n_positions int optional defaults to 1024 the maximum sequence length that this model might ever be used with typically set this to something large just in case e g 512 or 1024 or 2048 n_embd int optional defaults to 768 dimensionality of the embeddings and hidden states n_layer int optional defaults to 12 number of hidden layers in the transformer encoder n_head int optional defaults to 12 number of attention heads for each attention layer in the transformer encoder n_inner int optional dimensionality of the inner feed forward layers none will set it to 4 times n_embd activation_function str optional defaults to gelu_new activation function to be selected in the list relu silu gelu tanh gelu_new resid_pdrop float optional defaults to 0 1 the dropout probability for all fully connected layers in the embeddings encoder and pooler embd_pdrop float optional defaults to 0 1 the dropout ratio for the embeddings attn_pdrop float optional defaults to 0 1 the dropout ratio for the attention layer_norm_epsilon float optional defaults to 1e 05 the epsilon to use in the layer normalization layers initializer_range float optional defaults to 0 02 the standard deviation of the truncated_normal_initializer for initializing all weight matrices summary_type string optional defaults to cls_index argument used when doing sequence summary used in the models gpt2doubleheadsmodel and tfgpt2doubleheadsmodel has to be one of the following options last take the last token hidden state like xlnet first take the first token hidden state like bert mean take the mean of all tokens hidden states cls_index supply a tensor of classification token position like gpt gpt 2 attn not implemented now use multi head attention summary_use_proj bool optional defaults to true argument used when doing sequence summary used in the models gpt2doubleheadsmodel and tfgpt2doubleheadsmodel whether or not to add a projection after the vector extraction summary_activation str optional argument used when doing sequence summary used in for the multiple choice head in gpt2doubleheadsmodel pass tanh for a tanh activation to the output any other value will result in no activation summary_proj_to_labels bool optional defaults to true argument used when doing sequence summary used in the models gpt2doubleheadsmodel and tfgpt2doubleheadsmodel whether the projection outputs should have config num_labels or config hidden_size classes summary_first_dropout float optional defaults to 0 1 argument used when doing sequence summary used in the models gpt2doubleheadsmodel and tfgpt2doubleheadsmodel the dropout ratio to be used after the projection and activation scale_attn_weights bool optional defaults to true scale attention weights by dividing by sqrt hidden_size use_cache bool optional defaults to true whether or not the model should return the last key values attentions not used by all models bos_token_id int optional defaults to 50256 id of the beginning of sentence token in the vocabulary eos_token_id int optional defaults to 50256 id of the end of sentence token in the vocabulary scale_attn_by_inverse_layer_idx bool optional defaults to false whether to additionally scale attention weights by 1 layer_idx 1 reorder_and_upcast_attn bool optional defaults to false whether to scale keys k prior to computing attention dot product and upcast attention dot product softmax to float when training with mixed precision example python from transformers import gpt2config gpt2model initializing a gpt2 configuration configuration gpt2config initializing a model with random weights from the configuration model gpt2model configuration accessing the model configuration configuration model config todo how to do that better we need to order the input in the way they appears in the forward need to add the past_keys not using the same length for past_key_values
from collections import OrderedDict
from typing import Any, List, Mapping, Optional

from ... import PreTrainedTokenizer, TensorType, is_torch_available
from ...configuration_utils import PretrainedConfig
from ...onnx import OnnxConfigWithPast, PatchingSpec
from ...utils import logging


logger = logging.get_logger(__name__)

GPT2_PRETRAINED_CONFIG_ARCHIVE_MAP = {
    "gpt2": "https://huggingface.co/gpt2/resolve/main/config.json",
    "gpt2-medium": "https://huggingface.co/gpt2-medium/resolve/main/config.json",
    "gpt2-large": "https://huggingface.co/gpt2-large/resolve/main/config.json",
    "gpt2-xl": "https://huggingface.co/gpt2-xl/resolve/main/config.json",
    "distilgpt2": "https://huggingface.co/distilgpt2/resolve/main/config.json",
}


class GPT2Config(PretrainedConfig):
    

    model_type = "gpt2"
    keys_to_ignore_at_inference = ["past_key_values"]
    attribute_map = {
        "hidden_size": "n_embd",
        "max_position_embeddings": "n_positions",
        "num_attention_heads": "n_head",
        "num_hidden_layers": "n_layer",
    }

    def __init__(
        self,
        vocab_size=50257,
        n_positions=1024,
        n_embd=768,
        n_layer=12,
        n_head=12,
        n_inner=None,
        activation_function="gelu_new",
        resid_pdrop=0.1,
        embd_pdrop=0.1,
        attn_pdrop=0.1,
        layer_norm_epsilon=1e-5,
        initializer_range=0.02,
        summary_type="cls_index",
        summary_use_proj=True,
        summary_activation=None,
        summary_proj_to_labels=True,
        summary_first_dropout=0.1,
        scale_attn_weights=True,
        use_cache=True,
        bos_token_id=50256,
        eos_token_id=50256,
        scale_attn_by_inverse_layer_idx=False,
        reorder_and_upcast_attn=False,
        **kwargs,
    ):
        self.vocab_size = vocab_size
        self.n_positions = n_positions
        self.n_embd = n_embd
        self.n_layer = n_layer
        self.n_head = n_head
        self.n_inner = n_inner
        self.activation_function = activation_function
        self.resid_pdrop = resid_pdrop
        self.embd_pdrop = embd_pdrop
        self.attn_pdrop = attn_pdrop
        self.layer_norm_epsilon = layer_norm_epsilon
        self.initializer_range = initializer_range
        self.summary_type = summary_type
        self.summary_use_proj = summary_use_proj
        self.summary_activation = summary_activation
        self.summary_first_dropout = summary_first_dropout
        self.summary_proj_to_labels = summary_proj_to_labels
        self.scale_attn_weights = scale_attn_weights
        self.use_cache = use_cache
        self.scale_attn_by_inverse_layer_idx = scale_attn_by_inverse_layer_idx
        self.reorder_and_upcast_attn = reorder_and_upcast_attn

        self.bos_token_id = bos_token_id
        self.eos_token_id = eos_token_id

        super().__init__(bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs)


class GPT2OnnxConfig(OnnxConfigWithPast):
    def __init__(
        self,
        config: PretrainedConfig,
        task: str = "default",
        patching_specs: List[PatchingSpec] = None,
        use_past: bool = False,
    ):
        super().__init__(config, task=task, patching_specs=patching_specs, use_past=use_past)
        if not getattr(self._config, "pad_token_id", None):
            
            self._config.pad_token_id = 0

    @property
    def inputs(self) -> Mapping[str, Mapping[int, str]]:
        common_inputs = OrderedDict({"input_ids": {0: "batch", 1: "sequence"}})
        if self.use_past:
            self.fill_with_past_key_values_(common_inputs, direction="inputs")
            common_inputs["attention_mask"] = {0: "batch", 1: "past_sequence + sequence"}
        else:
            common_inputs["attention_mask"] = {0: "batch", 1: "sequence"}

        return common_inputs

    @property
    def num_layers(self) -> int:
        return self._config.n_layer

    @property
    def num_attention_heads(self) -> int:
        return self._config.n_head

    def generate_dummy_inputs(
        self,
        tokenizer: PreTrainedTokenizer,
        batch_size: int = -1,
        seq_length: int = -1,
        is_pair: bool = False,
        framework: Optional[TensorType] = None,
    ) -> Mapping[str, Any]:
        common_inputs = super(OnnxConfigWithPast, self).generate_dummy_inputs(
            tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework
        )

        
        ordered_inputs = OrderedDict({"input_ids": common_inputs["input_ids"]})

        
        if self.use_past:
            if not is_torch_available():
                raise ValueError("Cannot generate dummy past_keys inputs without PyTorch installed.")
            else:
                import torch

                batch, seqlen = common_inputs["input_ids"].shape
                
                past_key_values_length = seqlen + 2
                past_shape = (
                    batch,
                    self.num_attention_heads,
                    past_key_values_length,
                    self._config.hidden_size // self.num_attention_heads,
                )
                ordered_inputs["past_key_values"] = [
                    (torch.zeros(past_shape), torch.zeros(past_shape)) for _ in range(self.num_layers)
                ]

        ordered_inputs["attention_mask"] = common_inputs["attention_mask"]
        if self.use_past:
            mask_dtype = ordered_inputs["attention_mask"].dtype
            ordered_inputs["attention_mask"] = torch.cat(
                [ordered_inputs["attention_mask"], torch.ones(batch, past_key_values_length, dtype=mask_dtype)], dim=1
            )

        return ordered_inputs

    @property
    def default_onnx_opset(self) -> int:
        return 13