codingutf8 2022 the huggingface inc team 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 testing suite for the pytorch biogpt model import math import unittest from transformers import biogptconfig istorchavailable from transformers testingutils import requiretorch slow torchdevice from generation testutils import generationtestermixin from testconfigurationcommon import configtester from testmodelingcommon import modeltestermixin idstensor randomattentionmask from testpipelinemixin import pipelinetestermixin if istorchavailable import torch from transformers import biogptforcausallm biogptforsequenceclassification biogptfortokenclassification biogptmodel biogpttokenizer from transformers models biogpt modelingbiogpt import biogptpretrainedmodelarchivelist class biogptmodeltester def init self parent batchsize13 seqlength7 istrainingtrue useinputmasktrue usetokentypeidsfalse uselabelstrue vocabsize99 hiddensize32 numhiddenlayers2 numattentionheads4 intermediatesize37 hiddenactgelu hiddendropoutprob0 1 attentionprobsdropoutprob0 1 maxpositionembeddings512 typevocabsize16 typesequencelabelsize2 initializerrange0 02 numlabels3 numchoices4 scopenone self parent parent self batchsize batchsize self seqlength seqlength self istraining istraining self useinputmask useinputmask self usetokentypeids usetokentypeids self uselabels uselabels self vocabsize vocabsize self hiddensize hiddensize self numhiddenlayers numhiddenlayers self numattentionheads numattentionheads self intermediatesize intermediatesize self hiddenact hiddenact self hiddendropoutprob hiddendropoutprob self attentionprobsdropoutprob attentionprobsdropoutprob self maxpositionembeddings maxpositionembeddings self typevocabsize typevocabsize self typesequencelabelsize typesequencelabelsize self initializerrange initializerrange self numlabels numlabels self numchoices numchoices self scope scope def prepareconfigandinputsself inputids idstensorself batchsize self seqlength self vocabsize inputmask none if self useinputmask inputmask randomattentionmaskself batchsize self seqlength tokentypeids none if self usetokentypeids tokentypeids idstensorself batchsize self seqlength self typevocabsize sequencelabels none tokenlabels none choicelabels none if self uselabels sequencelabels idstensorself batchsize self typesequencelabelsize tokenlabels idstensorself batchsize self seqlength self numlabels choicelabels idstensorself batchsize self numchoices config self getconfig return config inputids tokentypeids inputmask sequencelabels tokenlabels choicelabels def getconfigself return biogptconfig vocabsizeself vocabsize hiddensizeself hiddensize numhiddenlayersself numhiddenlayers numattentionheadsself numattentionheads intermediatesizeself intermediatesize hiddenactself hiddenact hiddendropoutprobself hiddendropoutprob attentionprobsdropoutprobself attentionprobsdropoutprob maxpositionembeddingsself maxpositionembeddings typevocabsizeself typevocabsize isdecoderfalse initializerrangeself initializerrange def createandcheckmodel self config inputids tokentypeids inputmask sequencelabels tokenlabels choicelabels model biogptmodelconfigconfig model totorchdevice model eval result modelinputids attentionmaskinputmask result modelinputids self parent assertequalresult lasthiddenstate shape self batchsize self seqlength self hiddensize def createandcheckforcausallm self config inputids tokentypeids inputmask sequencelabels tokenlabels choicelabels encoderhiddenstates encoderattentionmask model biogptforcausallmconfigconfig model totorchdevice model eval result modelinputids attentionmaskinputmask tokentypeidstokentypeids labelstokenlabels self parent assertequalresult logits shape self batchsize self seqlength self vocabsize def createandcheckbiogptmodelattentionmaskpast self config inputids inputmask headmask tokentypeids args model biogptmodelconfigconfig model totorchdevice model eval create attention mask attnmask torch onesinputids shape dtypetorch long devicetorchdevice halfseqlength self seqlength 2 attnmask halfseqlength 0 first forward pass output past modelinputids attentionmaskattnmask totuple create hypothetical next token and extent to nextinputids nexttokens idstensorself batchsize 1 config vocabsize change a random masked slice from inputids randomseqidxtochange idstensor1 halfseqlength item 1 randomothernexttokens idstensorself batchsize 1 config vocabsize squeeze1 inputids randomseqidxtochange randomothernexttokens append to next inputids and attnmask nextinputids torch catinputids nexttokens dim1 attnmask torch cat attnmask torch onesattnmask shape0 1 dtypetorch long devicetorchdevice dim1 get two different outputs outputfromnopast modelnextinputids attentionmaskattnmasklasthiddenstate outputfrompast modelnexttokens pastkeyvaluespast attentionmaskattnmasklasthiddenstate select random slice randomsliceidx idstensor1 outputfrompast shape1 item outputfromnopastslice outputfromnopast 1 randomsliceidx detach outputfrompastslice outputfrompast 0 randomsliceidx detach test that outputs are equal for slice self parent asserttruetorch allcloseoutputfrompastslice outputfromnopastslice atol1e3 def createandcheckbiogptmodelpastlargeinputs self config inputids inputmask headmask tokentypeids args model biogptmodelconfigconfig totorchdevice eval attentionmask torch onesinputids shape dtypetorch long devicetorchdevice first forward pass outputs modelinputids attentionmaskattentionmask usecachetrue output pastkeyvalues outputs totuple create hypothetical multiple next token and extent to nextinputids nexttokens idstensorself batchsize 3 config vocabsize nextattnmask idstensorself batchsize 3 2 append to next inputids and nextinputids torch catinputids nexttokens dim1 nextattentionmask torch catattentionmask nextattnmask dim1 outputfromnopast modelnextinputids attentionmasknextattentionmasklasthiddenstate outputfrompast modelnexttokens attentionmasknextattentionmask pastkeyvaluespastkeyvalues lasthiddenstate select random slice randomsliceidx idstensor1 outputfrompast shape1 item outputfromnopastslice outputfromnopast 3 randomsliceidx detach outputfrompastslice outputfrompast randomsliceidx detach self parent asserttrueoutputfrompastslice shape1 nexttokens shape1 test that outputs are equal for slice self parent asserttruetorch allcloseoutputfrompastslice outputfromnopastslice atol1e3 def createandcheckforwardandbackwards self config inputids inputmask headmask tokentypeids args gradientcheckpointingfalse model biogptforcausallmconfig model totorchdevice if gradientcheckpointing model gradientcheckpointingenable result modelinputids labelsinputids self parent assertequalresult loss shape self parent assertequalresult logits shape self batchsize self seqlength self vocabsize result loss backward def createandcheckbiogptweightinitializationself config args model biogptmodelconfig modelstd model config initializerrange math sqrt2 model config numhiddenlayers for key in model statedict keys if cproj in key and weight in key self parent assertlessequalabstorch stdmodel statedictkey modelstd 0 001 self parent assertlessequalabstorch meanmodel statedictkey 0 0 0 01 def createandcheckbiogptfortokenclassification self config inputids inputmask headmask tokentypeids args config numlabels self numlabels model biogptfortokenclassificationconfig model totorchdevice model eval result modelinputids attentionmaskinputmask tokentypeidstokentypeids self parent assertequalresult logits shape self batchsize self seqlength self numlabels def prepareconfigandinputsforcommonself configandinputs self prepareconfigandinputs config inputids tokentypeids inputmask sequencelabels tokenlabels choicelabels configandinputs inputsdict inputids inputids attentionmask inputmask return config inputsdict requiretorch class biogptmodeltestmodeltestermixin generationtestermixin pipelinetestermixin unittest testcase allmodelclasses biogptmodel biogptforcausallm biogptforsequenceclassification biogptfortokenclassification if istorchavailable else allgenerativemodelclasses biogptforcausallm if istorchavailable else pipelinemodelmapping featureextraction biogptmodel textclassification biogptforsequenceclassification textgeneration biogptforcausallm tokenclassification biogptfortokenclassification zeroshot biogptforsequenceclassification if istorchavailable else testpruning false def setupself self modeltester biogptmodeltesterself self configtester configtesterself configclassbiogptconfig hiddensize37 def testconfigself self configtester runcommontests def testmodelself configandinputs self modeltester prepareconfigandinputs self modeltester createandcheckmodelconfigandinputs def testmodelvariousembeddingsself configandinputs self modeltester prepareconfigandinputs for type in absolute relativekey relativekeyquery configandinputs0 positionembeddingtype type self modeltester createandcheckmodelconfigandinputs def testbiogptmodelattmaskpastself configandinputs self modeltester prepareconfigandinputs self modeltester createandcheckbiogptmodelattentionmaskpastconfigandinputs def testbiogptgradientcheckpointingself configandinputs self modeltester prepareconfigandinputs self modeltester createandcheckforwardandbackwardsconfigandinputs gradientcheckpointingtrue def testbiogptmodelpastwithlargeinputsself configandinputs self modeltester prepareconfigandinputs self modeltester createandcheckbiogptmodelpastlargeinputsconfigandinputs def testbiogptweightinitializationself configandinputs self modeltester prepareconfigandinputs self modeltester createandcheckbiogptweightinitializationconfigandinputs def testbiogpttokenclassificationmodelself configandinputs self modeltester prepareconfigandinputs self modeltester createandcheckbiogptfortokenclassificationconfigandinputs slow def testbatchgenerationself model biogptforcausallm frompretrainedmicrosoftbiogpt model totorchdevice tokenizer biogpttokenizer frompretrainedmicrosoftbiogpt tokenizer paddingside left define pad token eos token 50256 tokenizer padtoken tokenizer eostoken model config padtokenid model config eostokenid use different length sentences to test batching sentences hello my dog is a little today i inputs tokenizersentences returntensorspt paddingtrue inputids inputsinputids totorchdevice outputs model generate inputidsinputids attentionmaskinputsattentionmask totorchdevice inputsnonpadded tokenizersentences0 returntensorspt inputids totorchdevice outputnonpadded model generateinputidsinputsnonpadded numpaddings inputsnonpadded shape1 inputsattentionmask1 long sum cpu item inputspadded tokenizersentences1 returntensorspt inputids totorchdevice outputpadded model generateinputidsinputspadded maxlengthmodel config maxlength numpaddings batchoutsentence tokenizer batchdecodeoutputs skipspecialtokenstrue nonpaddedsentence tokenizer decodeoutputnonpadded0 skipspecialtokenstrue paddedsentence tokenizer decodeoutputpadded0 skipspecialtokenstrue expectedoutputsentence hello my dog is a little bit bigger than a little bit today i have a good idea of how to use the information self assertlistequalexpectedoutputsentence batchoutsentence self assertlistequalexpectedoutputsentence nonpaddedsentence paddedsentence slow def testmodelfrompretrainedself for modelname in biogptpretrainedmodelarchivelist 1 model biogptmodel frompretrainedmodelname self assertisnotnonemodel copied from tests models opt testmodelingopt optmodeltest testoptsequenceclassificationmodel with optbiogpt optbiogpt prepareconfigandinputsprepareconfigandinputsforcommon def testbiogptsequenceclassificationmodelself config inputdict self modeltester prepareconfigandinputsforcommon config numlabels 3 inputids inputdictinputids attentionmask inputids ne1 totorchdevice sequencelabels idstensorself modeltester batchsize self modeltester typesequencelabelsize model biogptforsequenceclassificationconfig model totorchdevice model eval result modelinputids attentionmaskattentionmask labelssequencelabels self assertequalresult logits shape self modeltester batchsize self modeltester numlabels copied from tests models opt testmodelingopt optmodeltest testoptsequenceclassificationmodelformultilabel with optbiogpt optbiogpt prepareconfigandinputsprepareconfigandinputsforcommon def testbiogptsequenceclassificationmodelformultilabelself config inputdict self modeltester prepareconfigandinputsforcommon config numlabels 3 config problemtype multilabelclassification inputids inputdictinputids attentionmask inputids ne1 totorchdevice sequencelabels idstensor self modeltester batchsize config numlabels self modeltester typesequencelabelsize totorch float model biogptforsequenceclassificationconfig model totorchdevice model eval result modelinputids attentionmaskattentionmask labelssequencelabels self assertequalresult logits shape self modeltester batchsize self modeltester numlabels requiretorch class biogptmodelintegrationtestunittest testcase slow def testinferencelmheadmodelself model biogptforcausallm frompretrainedmicrosoftbiogpt inputids torch tensor2 4805 9 656 21 output modelinputids0 vocabsize 42384 expectedshape torch size1 5 vocabsize self assertequaloutput shape expectedshape expectedslice torch tensor 9 5236 9 8918 10 4557 11 0469 9 6423 8 1022 8 8664 7 8826 5 5325 self asserttruetorch allcloseoutput 3 3 expectedslice atol1e4 slow def testbiogptgenerationself tokenizer biogpttokenizer frompretrainedmicrosoftbiogpt model biogptforcausallm frompretrainedmicrosoftbiogpt model totorchdevice torch manualseed0 tokenized tokenizercovid19 is returntensorspt totorchdevice outputids model generate tokenized minlength100 maxlength1024 numbeams5 earlystoppingtrue outputstr tokenizer decodeoutputids0 skipspecialtokenstrue expectedoutputstr covid19 is a global pandemic caused by severe acute respiratory syndrome coronavirus 2 sarscov2 the causative agent of coronavirus disease 2019 covid19 which has spread to more than 200 countries and territories including the united states us canada australia new zealand the united kingdom uk and the united states of america usa as of march 11 2020 with more than 800 000 confirmed cases and more than 800 000 deaths self assertequaloutputstr expectedoutputstr coding utf 8 2022 the huggingface inc team 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 testing suite for the pytorch biogpt model create attention mask first forward pass create hypothetical next token and extent to next_input_ids change a random masked slice from input_ids append to next input_ids and attn_mask get two different outputs select random slice test that outputs are equal for slice first forward pass create hypothetical multiple next token and extent to next_input_ids append to next input_ids and select random slice test that outputs are equal for slice define pad token eos token 50256 use different length sentences to test batching copied from tests models opt test_modeling_opt optmodeltest test_opt_sequence_classification_model with opt biogpt opt biogpt prepare_config_and_inputs prepare_config_and_inputs_for_common copied from tests models opt test_modeling_opt optmodeltest test_opt_sequence_classification_model_for_multi_label with opt biogpt opt biogpt prepare_config_and_inputs prepare_config_and_inputs_for_common
import math
import unittest

from transformers import BioGptConfig, is_torch_available
from transformers.testing_utils import require_torch, slow, torch_device

from ...generation.test_utils import GenerationTesterMixin
from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
    import torch

    from transformers import (
        BioGptForCausalLM,
        BioGptForSequenceClassification,
        BioGptForTokenClassification,
        BioGptModel,
        BioGptTokenizer,
    )
    from transformers.models.biogpt.modeling_biogpt import BIOGPT_PRETRAINED_MODEL_ARCHIVE_LIST


class BioGptModelTester:
    def __init__(
        self,
        parent,
        batch_size=13,
        seq_length=7,
        is_training=True,
        use_input_mask=True,
        use_token_type_ids=False,
        use_labels=True,
        vocab_size=99,
        hidden_size=32,
        num_hidden_layers=2,
        num_attention_heads=4,
        intermediate_size=37,
        hidden_act="gelu",
        hidden_dropout_prob=0.1,
        attention_probs_dropout_prob=0.1,
        max_position_embeddings=512,
        type_vocab_size=16,
        type_sequence_label_size=2,
        initializer_range=0.02,
        num_labels=3,
        num_choices=4,
        scope=None,
    ):
        self.parent = parent
        self.batch_size = batch_size
        self.seq_length = seq_length
        self.is_training = is_training
        self.use_input_mask = use_input_mask
        self.use_token_type_ids = use_token_type_ids
        self.use_labels = use_labels
        self.vocab_size = vocab_size
        self.hidden_size = hidden_size
        self.num_hidden_layers = num_hidden_layers
        self.num_attention_heads = num_attention_heads
        self.intermediate_size = intermediate_size
        self.hidden_act = hidden_act
        self.hidden_dropout_prob = hidden_dropout_prob
        self.attention_probs_dropout_prob = attention_probs_dropout_prob
        self.max_position_embeddings = max_position_embeddings
        self.type_vocab_size = type_vocab_size
        self.type_sequence_label_size = type_sequence_label_size
        self.initializer_range = initializer_range
        self.num_labels = num_labels
        self.num_choices = num_choices
        self.scope = scope

    def prepare_config_and_inputs(self):
        input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size)

        input_mask = None
        if self.use_input_mask:
            input_mask = random_attention_mask([self.batch_size, self.seq_length])

        token_type_ids = None
        if self.use_token_type_ids:
            token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size)

        sequence_labels = None
        token_labels = None
        choice_labels = None
        if self.use_labels:
            sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size)
            token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels)
            choice_labels = ids_tensor([self.batch_size], self.num_choices)

        config = self.get_config()

        return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels

    def get_config(self):
        return BioGptConfig(
            vocab_size=self.vocab_size,
            hidden_size=self.hidden_size,
            num_hidden_layers=self.num_hidden_layers,
            num_attention_heads=self.num_attention_heads,
            intermediate_size=self.intermediate_size,
            hidden_act=self.hidden_act,
            hidden_dropout_prob=self.hidden_dropout_prob,
            attention_probs_dropout_prob=self.attention_probs_dropout_prob,
            max_position_embeddings=self.max_position_embeddings,
            type_vocab_size=self.type_vocab_size,
            is_decoder=False,
            initializer_range=self.initializer_range,
        )

    def create_and_check_model(
        self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels
    ):
        model = BioGptModel(config=config)
        model.to(torch_device)
        model.eval()
        result = model(input_ids, attention_mask=input_mask)
        result = model(input_ids)
        self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size))

    def create_and_check_for_causal_lm(
        self,
        config,
        input_ids,
        token_type_ids,
        input_mask,
        sequence_labels,
        token_labels,
        choice_labels,
        encoder_hidden_states,
        encoder_attention_mask,
    ):
        model = BioGptForCausalLM(config=config)
        model.to(torch_device)
        model.eval()
        result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels)
        self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size))

    def create_and_check_biogpt_model_attention_mask_past(
        self, config, input_ids, input_mask, head_mask, token_type_ids, *args
    ):
        model = BioGptModel(config=config)
        model.to(torch_device)
        model.eval()

        
        attn_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device)
        half_seq_length = self.seq_length // 2
        attn_mask[:, half_seq_length:] = 0

        
        output, past = model(input_ids, attention_mask=attn_mask).to_tuple()

        
        next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size)

        
        random_seq_idx_to_change = ids_tensor((1,), half_seq_length).item() + 1
        random_other_next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size).squeeze(-1)
        input_ids[:, -random_seq_idx_to_change] = random_other_next_tokens

        
        next_input_ids = torch.cat([input_ids, next_tokens], dim=-1)
        attn_mask = torch.cat(
            [attn_mask, torch.ones((attn_mask.shape[0], 1), dtype=torch.long, device=torch_device)],
            dim=1,
        )

        
        output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"]
        output_from_past = model(next_tokens, past_key_values=past, attention_mask=attn_mask)["last_hidden_state"]

        
        random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item()
        output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach()
        output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach()

        
        self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3))

    def create_and_check_biogpt_model_past_large_inputs(
        self, config, input_ids, input_mask, head_mask, token_type_ids, *args
    ):
        model = BioGptModel(config=config).to(torch_device).eval()

        attention_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device)

        
        outputs = model(input_ids, attention_mask=attention_mask, use_cache=True)

        output, past_key_values = outputs.to_tuple()

        
        next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size)
        next_attn_mask = ids_tensor((self.batch_size, 3), 2)

        
        next_input_ids = torch.cat([input_ids, next_tokens], dim=-1)
        next_attention_mask = torch.cat([attention_mask, next_attn_mask], dim=-1)

        output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask)["last_hidden_state"]
        output_from_past = model(next_tokens, attention_mask=next_attention_mask, past_key_values=past_key_values)[
            "last_hidden_state"
        ]

        
        random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item()
        output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach()
        output_from_past_slice = output_from_past[:, :, random_slice_idx].detach()

        self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1])

        
        self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3))

    def create_and_check_forward_and_backwards(
        self, config, input_ids, input_mask, head_mask, token_type_ids, *args, gradient_checkpointing=False
    ):
        model = BioGptForCausalLM(config)
        model.to(torch_device)
        if gradient_checkpointing:
            model.gradient_checkpointing_enable()

        result = model(input_ids, labels=input_ids)
        self.parent.assertEqual(result.loss.shape, ())
        self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size))
        result.loss.backward()

    def create_and_check_biogpt_weight_initialization(self, config, *args):
        model = BioGptModel(config)
        model_std = model.config.initializer_range / math.sqrt(2 * model.config.num_hidden_layers)
        for key in model.state_dict().keys():
            if "c_proj" in key and "weight" in key:
                self.parent.assertLessEqual(abs(torch.std(model.state_dict()[key]) - model_std), 0.001)
                self.parent.assertLessEqual(abs(torch.mean(model.state_dict()[key]) - 0.0), 0.01)

    def create_and_check_biogpt_for_token_classification(
        self, config, input_ids, input_mask, head_mask, token_type_ids, *args
    ):
        config.num_labels = self.num_labels
        model = BioGptForTokenClassification(config)
        model.to(torch_device)
        model.eval()
        result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids)
        self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels))

    def prepare_config_and_inputs_for_common(self):
        config_and_inputs = self.prepare_config_and_inputs()
        (
            config,
            input_ids,
            token_type_ids,
            input_mask,
            sequence_labels,
            token_labels,
            choice_labels,
        ) = config_and_inputs
        inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask}
        return config, inputs_dict


@require_torch
class BioGptModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase):
    all_model_classes = (
        (BioGptModel, BioGptForCausalLM, BioGptForSequenceClassification, BioGptForTokenClassification)
        if is_torch_available()
        else ()
    )
    all_generative_model_classes = (BioGptForCausalLM,) if is_torch_available() else ()
    pipeline_model_mapping = (
        {
            "feature-extraction": BioGptModel,
            "text-classification": BioGptForSequenceClassification,
            "text-generation": BioGptForCausalLM,
            "token-classification": BioGptForTokenClassification,
            "zero-shot": BioGptForSequenceClassification,
        }
        if is_torch_available()
        else {}
    )
    test_pruning = False

    def setUp(self):
        self.model_tester = BioGptModelTester(self)
        self.config_tester = ConfigTester(self, config_class=BioGptConfig, hidden_size=37)

    def test_config(self):
        self.config_tester.run_common_tests()

    def test_model(self):
        config_and_inputs = self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_model(*config_and_inputs)

    def test_model_various_embeddings(self):
        config_and_inputs = self.model_tester.prepare_config_and_inputs()
        for type in ["absolute", "relative_key", "relative_key_query"]:
            config_and_inputs[0].position_embedding_type = type
            self.model_tester.create_and_check_model(*config_and_inputs)

    def test_biogpt_model_att_mask_past(self):
        config_and_inputs = self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_biogpt_model_attention_mask_past(*config_and_inputs)

    def test_biogpt_gradient_checkpointing(self):
        config_and_inputs = self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs, gradient_checkpointing=True)

    def test_biogpt_model_past_with_large_inputs(self):
        config_and_inputs = self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_biogpt_model_past_large_inputs(*config_and_inputs)

    def test_biogpt_weight_initialization(self):
        config_and_inputs = self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_biogpt_weight_initialization(*config_and_inputs)

    def test_biogpt_token_classification_model(self):
        config_and_inputs = self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_biogpt_for_token_classification(*config_and_inputs)

    @slow
    def test_batch_generation(self):
        model = BioGptForCausalLM.from_pretrained("microsoft/biogpt")
        model.to(torch_device)
        tokenizer = BioGptTokenizer.from_pretrained("microsoft/biogpt")

        tokenizer.padding_side = "left"

        
        tokenizer.pad_token = tokenizer.eos_token
        model.config.pad_token_id = model.config.eos_token_id

        
        sentences = [
            "Hello, my dog is a little",
            "Today, I",
        ]

        inputs = tokenizer(sentences, return_tensors="pt", padding=True)
        input_ids = inputs["input_ids"].to(torch_device)

        outputs = model.generate(
            input_ids=input_ids,
            attention_mask=inputs["attention_mask"].to(torch_device),
        )

        inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device)
        output_non_padded = model.generate(input_ids=inputs_non_padded)

        num_paddings = inputs_non_padded.shape[-1] - inputs["attention_mask"][-1].long().sum().cpu().item()
        inputs_padded = tokenizer(sentences[1], return_tensors="pt").input_ids.to(torch_device)
        output_padded = model.generate(input_ids=inputs_padded, max_length=model.config.max_length - num_paddings)

        batch_out_sentence = tokenizer.batch_decode(outputs, skip_special_tokens=True)
        non_padded_sentence = tokenizer.decode(output_non_padded[0], skip_special_tokens=True)
        padded_sentence = tokenizer.decode(output_padded[0], skip_special_tokens=True)

        expected_output_sentence = [
            "Hello, my dog is a little bit bigger than a little bit.",
            "Today, I have a good idea of how to use the information",
        ]
        self.assertListEqual(expected_output_sentence, batch_out_sentence)
        self.assertListEqual(expected_output_sentence, [non_padded_sentence, padded_sentence])

    @slow
    def test_model_from_pretrained(self):
        for model_name in BIOGPT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
            model = BioGptModel.from_pretrained(model_name)
            self.assertIsNotNone(model)

    
    def test_biogpt_sequence_classification_model(self):
        config, input_dict = self.model_tester.prepare_config_and_inputs_for_common()
        config.num_labels = 3
        input_ids = input_dict["input_ids"]
        attention_mask = input_ids.ne(1).to(torch_device)
        sequence_labels = ids_tensor([self.model_tester.batch_size], self.model_tester.type_sequence_label_size)
        model = BioGptForSequenceClassification(config)
        model.to(torch_device)
        model.eval()
        result = model(input_ids, attention_mask=attention_mask, labels=sequence_labels)
        self.assertEqual(result.logits.shape, (self.model_tester.batch_size, self.model_tester.num_labels))

    
    def test_biogpt_sequence_classification_model_for_multi_label(self):
        config, input_dict = self.model_tester.prepare_config_and_inputs_for_common()
        config.num_labels = 3
        config.problem_type = "multi_label_classification"
        input_ids = input_dict["input_ids"]
        attention_mask = input_ids.ne(1).to(torch_device)
        sequence_labels = ids_tensor(
            [self.model_tester.batch_size, config.num_labels], self.model_tester.type_sequence_label_size
        ).to(torch.float)
        model = BioGptForSequenceClassification(config)
        model.to(torch_device)
        model.eval()
        result = model(input_ids, attention_mask=attention_mask, labels=sequence_labels)
        self.assertEqual(result.logits.shape, (self.model_tester.batch_size, self.model_tester.num_labels))


@require_torch
class BioGptModelIntegrationTest(unittest.TestCase):
    @slow
    def test_inference_lm_head_model(self):
        model = BioGptForCausalLM.from_pretrained("microsoft/biogpt")
        input_ids = torch.tensor([[2, 4805, 9, 656, 21]])
        output = model(input_ids)[0]

        vocab_size = 42384

        expected_shape = torch.Size((1, 5, vocab_size))
        self.assertEqual(output.shape, expected_shape)

        expected_slice = torch.tensor(
            [[[-9.5236, -9.8918, 10.4557], [-11.0469, -9.6423, 8.1022], [-8.8664, -7.8826, 5.5325]]]
        )

        self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4))

    @slow
    def test_biogpt_generation(self):
        tokenizer = BioGptTokenizer.from_pretrained("microsoft/biogpt")
        model = BioGptForCausalLM.from_pretrained("microsoft/biogpt")
        model.to(torch_device)

        torch.manual_seed(0)
        tokenized = tokenizer("COVID-19 is", return_tensors="pt").to(torch_device)
        output_ids = model.generate(
            **tokenized,
            min_length=100,
            max_length=1024,
            num_beams=5,
            early_stopping=True,
        )
        output_str = tokenizer.decode(output_ids[0], skip_special_tokens=True)

        EXPECTED_OUTPUT_STR = (
            "COVID-19 is a global pandemic caused by severe acute respiratory syndrome coronavirus 2 (SARS-CoV-2), the"
            " causative agent of coronavirus disease 2019 (COVID-19), which has spread to more than 200 countries and"
            " territories, including the United States (US), Canada, Australia, New Zealand, the United Kingdom (UK),"
            " and the United States of America (USA), as of March 11, 2020, with more than 800,000 confirmed cases and"
            " more than 800,000 deaths."
        )
        self.assertEqual(output_str, EXPECTED_OUTPUT_STR)