transformers
309 строк · 11.6 Кб
1# coding=utf-8
2# Copyright 2020 The HuggingFace Team. All rights reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
17import unittest
18
19from transformers import is_torch_available
20from transformers.testing_utils import require_torch, slow, torch_device
21
22from ...generation.test_utils import GenerationTesterMixin
23from ...test_configuration_common import ConfigTester
24from ...test_modeling_common import ModelTesterMixin, ids_tensor
25from ...test_pipeline_mixin import PipelineTesterMixin
26
27
28if is_torch_available():
29import torch
30
31from transformers import (
32OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST,
33OpenAIGPTConfig,
34OpenAIGPTDoubleHeadsModel,
35OpenAIGPTForSequenceClassification,
36OpenAIGPTLMHeadModel,
37OpenAIGPTModel,
38)
39
40
41class OpenAIGPTModelTester:
42def __init__(
43self,
44parent,
45batch_size=13,
46seq_length=7,
47is_training=True,
48use_token_type_ids=True,
49use_labels=True,
50vocab_size=99,
51hidden_size=32,
52num_hidden_layers=2,
53num_attention_heads=4,
54intermediate_size=37,
55hidden_act="gelu",
56hidden_dropout_prob=0.1,
57attention_probs_dropout_prob=0.1,
58max_position_embeddings=512,
59type_vocab_size=16,
60type_sequence_label_size=2,
61initializer_range=0.02,
62num_labels=3,
63num_choices=4,
64scope=None,
65):
66self.parent = parent
67self.batch_size = batch_size
68self.seq_length = seq_length
69self.is_training = is_training
70self.use_token_type_ids = use_token_type_ids
71self.use_labels = use_labels
72self.vocab_size = vocab_size
73self.hidden_size = hidden_size
74self.num_hidden_layers = num_hidden_layers
75self.num_attention_heads = num_attention_heads
76self.intermediate_size = intermediate_size
77self.hidden_act = hidden_act
78self.hidden_dropout_prob = hidden_dropout_prob
79self.attention_probs_dropout_prob = attention_probs_dropout_prob
80self.max_position_embeddings = max_position_embeddings
81self.type_vocab_size = type_vocab_size
82self.type_sequence_label_size = type_sequence_label_size
83self.initializer_range = initializer_range
84self.num_labels = num_labels
85self.num_choices = num_choices
86self.scope = scope
87self.pad_token_id = self.vocab_size - 1
88
89def prepare_config_and_inputs(self):
90input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size)
91
92token_type_ids = None
93if self.use_token_type_ids:
94token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size)
95
96sequence_labels = None
97token_labels = None
98choice_labels = None
99if self.use_labels:
100sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size)
101token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels)
102choice_labels = ids_tensor([self.batch_size], self.num_choices)
103
104config = OpenAIGPTConfig(
105vocab_size=self.vocab_size,
106n_embd=self.hidden_size,
107n_layer=self.num_hidden_layers,
108n_head=self.num_attention_heads,
109# intermediate_size=self.intermediate_size,
110# hidden_act=self.hidden_act,
111# hidden_dropout_prob=self.hidden_dropout_prob,
112# attention_probs_dropout_prob=self.attention_probs_dropout_prob,
113n_positions=self.max_position_embeddings,
114# type_vocab_size=self.type_vocab_size,
115# initializer_range=self.initializer_range
116pad_token_id=self.pad_token_id,
117)
118
119head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2)
120
121return (
122config,
123input_ids,
124head_mask,
125token_type_ids,
126sequence_labels,
127token_labels,
128choice_labels,
129)
130
131def create_and_check_openai_gpt_model(self, config, input_ids, head_mask, token_type_ids, *args):
132model = OpenAIGPTModel(config=config)
133model.to(torch_device)
134model.eval()
135
136result = model(input_ids, token_type_ids=token_type_ids, head_mask=head_mask)
137result = model(input_ids, token_type_ids=token_type_ids)
138result = model(input_ids)
139
140self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size))
141
142def create_and_check_lm_head_model(self, config, input_ids, head_mask, token_type_ids, *args):
143model = OpenAIGPTLMHeadModel(config)
144model.to(torch_device)
145model.eval()
146
147result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids)
148self.parent.assertEqual(result.loss.shape, ())
149self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size))
150
151def create_and_check_double_lm_head_model(self, config, input_ids, head_mask, token_type_ids, *args):
152model = OpenAIGPTDoubleHeadsModel(config)
153model.to(torch_device)
154model.eval()
155
156result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids)
157self.parent.assertEqual(result.loss.shape, ())
158self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size))
159
160def create_and_check_openai_gpt_for_sequence_classification(
161self, config, input_ids, head_mask, token_type_ids, *args
162):
163config.num_labels = self.num_labels
164model = OpenAIGPTForSequenceClassification(config)
165model.to(torch_device)
166model.eval()
167
168sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size)
169result = model(input_ids, token_type_ids=token_type_ids, labels=sequence_labels)
170self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels))
171
172def prepare_config_and_inputs_for_common(self):
173config_and_inputs = self.prepare_config_and_inputs()
174(
175config,
176input_ids,
177head_mask,
178token_type_ids,
179sequence_labels,
180token_labels,
181choice_labels,
182) = config_and_inputs
183inputs_dict = {
184"input_ids": input_ids,
185"token_type_ids": token_type_ids,
186"head_mask": head_mask,
187}
188
189return config, inputs_dict
190
191
192@require_torch
193class OpenAIGPTModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase):
194all_model_classes = (
195(OpenAIGPTModel, OpenAIGPTLMHeadModel, OpenAIGPTDoubleHeadsModel, OpenAIGPTForSequenceClassification)
196if is_torch_available()
197else ()
198)
199all_generative_model_classes = (
200(OpenAIGPTLMHeadModel,) if is_torch_available() else ()
201) # TODO (PVP): Add Double HeadsModel when generate() function is changed accordingly
202pipeline_model_mapping = (
203{
204"feature-extraction": OpenAIGPTModel,
205"text-classification": OpenAIGPTForSequenceClassification,
206"text-generation": OpenAIGPTLMHeadModel,
207"zero-shot": OpenAIGPTForSequenceClassification,
208}
209if is_torch_available()
210else {}
211)
212
213# TODO: Fix the failed tests
214def is_pipeline_test_to_skip(
215self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name
216):
217if pipeline_test_casse_name == "ZeroShotClassificationPipelineTests":
218# Get `tokenizer does not have a padding token` error for both fast/slow tokenizers.
219# `OpenAIGPTConfig` was never used in pipeline tests, either because of a missing checkpoint or because a
220# tiny config could not be created.
221return True
222
223return False
224
225# special case for DoubleHeads model
226def _prepare_for_class(self, inputs_dict, model_class, return_labels=False):
227inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels)
228
229if return_labels:
230if model_class.__name__ == "OpenAIGPTDoubleHeadsModel":
231inputs_dict["labels"] = torch.zeros(
232(self.model_tester.batch_size, self.model_tester.num_choices, self.model_tester.seq_length),
233dtype=torch.long,
234device=torch_device,
235)
236inputs_dict["input_ids"] = inputs_dict["labels"]
237inputs_dict["token_type_ids"] = inputs_dict["labels"]
238inputs_dict["mc_token_ids"] = torch.zeros(
239(self.model_tester.batch_size, self.model_tester.num_choices),
240dtype=torch.long,
241device=torch_device,
242)
243inputs_dict["mc_labels"] = torch.zeros(
244self.model_tester.batch_size, dtype=torch.long, device=torch_device
245)
246return inputs_dict
247
248def setUp(self):
249self.model_tester = OpenAIGPTModelTester(self)
250self.config_tester = ConfigTester(self, config_class=OpenAIGPTConfig, n_embd=37)
251
252def test_config(self):
253self.config_tester.run_common_tests()
254
255def test_openai_gpt_model(self):
256config_and_inputs = self.model_tester.prepare_config_and_inputs()
257self.model_tester.create_and_check_openai_gpt_model(*config_and_inputs)
258
259def test_openai_gpt_lm_head_model(self):
260config_and_inputs = self.model_tester.prepare_config_and_inputs()
261self.model_tester.create_and_check_lm_head_model(*config_and_inputs)
262
263def test_openai_gpt_double_lm_head_model(self):
264config_and_inputs = self.model_tester.prepare_config_and_inputs()
265self.model_tester.create_and_check_double_lm_head_model(*config_and_inputs)
266
267def test_openai_gpt_classification_model(self):
268config_and_inputs = self.model_tester.prepare_config_and_inputs()
269self.model_tester.create_and_check_openai_gpt_for_sequence_classification(*config_and_inputs)
270
271@slow
272def test_model_from_pretrained(self):
273for model_name in OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
274model = OpenAIGPTModel.from_pretrained(model_name)
275self.assertIsNotNone(model)
276
277
278@require_torch
279class OPENAIGPTModelLanguageGenerationTest(unittest.TestCase):
280@slow
281def test_lm_generate_openai_gpt(self):
282model = OpenAIGPTLMHeadModel.from_pretrained("openai-community/openai-gpt")
283model.to(torch_device)
284input_ids = torch.tensor([[481, 4735, 544]], dtype=torch.long, device=torch_device) # the president is
285expected_output_ids = [
286481,
2874735,
288544,
289246,
290963,
291870,
292762,
293239,
294244,
29540477,
296244,
297249,
298719,
299881,
300487,
301544,
302240,
303244,
304603,
305481,
306] # the president is a very good man. " \n " i\'m sure he is, " said the
307
308output_ids = model.generate(input_ids, do_sample=False)
309self.assertListEqual(output_ids[0].tolist(), expected_output_ids)
310