transformers
325 строк · 11.5 Кб
1# coding=utf-8
2# Copyright 2022 The HuggingFace Inc. 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
17from __future__ import annotations
18
19import unittest
20
21from transformers import EsmConfig, is_tf_available
22from transformers.testing_utils import require_tf, slow
23
24from ...test_configuration_common import ConfigTester
25from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask
26from ...test_pipeline_mixin import PipelineTesterMixin
27
28
29if is_tf_available():
30import numpy
31import tensorflow as tf
32
33from transformers.modeling_tf_utils import keras
34from transformers.models.esm.modeling_tf_esm import (
35TF_ESM_PRETRAINED_MODEL_ARCHIVE_LIST,
36TFEsmForMaskedLM,
37TFEsmForSequenceClassification,
38TFEsmForTokenClassification,
39TFEsmModel,
40)
41
42
43# copied from tests.test_modeling_tf_roberta
44class TFEsmModelTester:
45def __init__(
46self,
47parent,
48):
49self.parent = parent
50self.batch_size = 13
51self.seq_length = 7
52self.is_training = True
53self.use_input_mask = True
54self.use_labels = True
55self.vocab_size = 99
56self.hidden_size = 32
57self.num_hidden_layers = 2
58self.num_attention_heads = 4
59self.intermediate_size = 37
60self.hidden_act = "gelu"
61self.hidden_dropout_prob = 0.1
62self.attention_probs_dropout_prob = 0.1
63self.max_position_embeddings = 512
64self.type_vocab_size = 16
65self.type_sequence_label_size = 2
66self.initializer_range = 0.02
67self.num_labels = 3
68self.num_choices = 4
69self.scope = None
70
71def prepare_config_and_inputs(self):
72input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size)
73
74input_mask = None
75if self.use_input_mask:
76input_mask = random_attention_mask([self.batch_size, self.seq_length])
77
78sequence_labels = None
79token_labels = None
80choice_labels = None
81if self.use_labels:
82sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size)
83token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels)
84choice_labels = ids_tensor([self.batch_size], self.num_choices)
85
86config = EsmConfig(
87vocab_size=self.vocab_size,
88hidden_size=self.hidden_size,
89num_hidden_layers=self.num_hidden_layers,
90pad_token_id=1,
91num_attention_heads=self.num_attention_heads,
92intermediate_size=self.intermediate_size,
93hidden_act=self.hidden_act,
94hidden_dropout_prob=self.hidden_dropout_prob,
95attention_probs_dropout_prob=self.attention_probs_dropout_prob,
96max_position_embeddings=self.max_position_embeddings,
97type_vocab_size=self.type_vocab_size,
98initializer_range=self.initializer_range,
99)
100
101return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
102
103def prepare_config_and_inputs_for_decoder(self):
104(
105config,
106input_ids,
107input_mask,
108sequence_labels,
109token_labels,
110choice_labels,
111) = self.prepare_config_and_inputs()
112
113config.is_decoder = True
114encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size])
115encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2)
116
117return (
118config,
119input_ids,
120input_mask,
121sequence_labels,
122token_labels,
123choice_labels,
124encoder_hidden_states,
125encoder_attention_mask,
126)
127
128def create_and_check_model(self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels):
129model = TFEsmModel(config=config)
130inputs = {"input_ids": input_ids, "attention_mask": input_mask}
131result = model(inputs)
132
133inputs = [input_ids, input_mask]
134result = model(inputs)
135
136result = model(input_ids)
137
138self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size))
139
140def create_and_check_model_as_decoder(
141self,
142config,
143input_ids,
144input_mask,
145sequence_labels,
146token_labels,
147choice_labels,
148encoder_hidden_states,
149encoder_attention_mask,
150):
151config.add_cross_attention = True
152
153model = TFEsmModel(config=config)
154inputs = {
155"input_ids": input_ids,
156"attention_mask": input_mask,
157"encoder_hidden_states": encoder_hidden_states,
158"encoder_attention_mask": encoder_attention_mask,
159}
160result = model(inputs)
161
162inputs = [input_ids, input_mask]
163result = model(inputs, encoder_hidden_states=encoder_hidden_states)
164
165# Also check the case where encoder outputs are not passed
166result = model(input_ids, attention_mask=input_mask)
167
168self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size))
169
170def create_and_check_for_masked_lm(
171self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
172):
173model = TFEsmForMaskedLM(config=config)
174result = model([input_ids, input_mask])
175self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size))
176
177def create_and_check_for_token_classification(
178self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
179):
180config.num_labels = self.num_labels
181model = TFEsmForTokenClassification(config=config)
182inputs = {"input_ids": input_ids, "attention_mask": input_mask}
183result = model(inputs)
184self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels))
185
186def prepare_config_and_inputs_for_common(self):
187config_and_inputs = self.prepare_config_and_inputs()
188(
189config,
190input_ids,
191input_mask,
192sequence_labels,
193token_labels,
194choice_labels,
195) = config_and_inputs
196inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask}
197return config, inputs_dict
198
199
200@require_tf
201class TFEsmModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase):
202all_model_classes = (
203(
204TFEsmModel,
205TFEsmForMaskedLM,
206TFEsmForSequenceClassification,
207TFEsmForTokenClassification,
208)
209if is_tf_available()
210else ()
211)
212pipeline_model_mapping = (
213{
214"feature-extraction": TFEsmModel,
215"fill-mask": TFEsmForMaskedLM,
216"text-classification": TFEsmForSequenceClassification,
217"token-classification": TFEsmForTokenClassification,
218"zero-shot": TFEsmForSequenceClassification,
219}
220if is_tf_available()
221else {}
222)
223test_head_masking = False
224test_onnx = False
225
226def setUp(self):
227self.model_tester = TFEsmModelTester(self)
228self.config_tester = ConfigTester(self, config_class=EsmConfig, hidden_size=37)
229
230def test_config(self):
231self.config_tester.run_common_tests()
232
233def test_model(self):
234"""Test the base model"""
235config_and_inputs = self.model_tester.prepare_config_and_inputs()
236self.model_tester.create_and_check_model(*config_and_inputs)
237
238def test_model_as_decoder(self):
239"""Test the base model as a decoder (of an encoder-decoder architecture)
240
241is_deocder=True + cross_attention + pass encoder outputs
242"""
243config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder()
244self.model_tester.create_and_check_model_as_decoder(*config_and_inputs)
245
246def test_for_masked_lm(self):
247config_and_inputs = self.model_tester.prepare_config_and_inputs()
248self.model_tester.create_and_check_for_masked_lm(*config_and_inputs)
249
250def test_for_token_classification(self):
251config_and_inputs = self.model_tester.prepare_config_and_inputs()
252self.model_tester.create_and_check_for_token_classification(*config_and_inputs)
253
254@slow
255def test_model_from_pretrained(self):
256for model_name in TF_ESM_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
257model = TFEsmModel.from_pretrained(model_name)
258self.assertIsNotNone(model)
259
260@unittest.skip("Protein models do not support embedding resizing.")
261def test_resize_token_embeddings(self):
262pass
263
264@unittest.skip("Protein models do not support embedding resizing.")
265def test_save_load_after_resize_token_embeddings(self):
266pass
267
268def test_model_common_attributes(self):
269config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
270
271for model_class in self.all_model_classes:
272model = model_class(config)
273assert isinstance(model.get_input_embeddings(), keras.layers.Layer)
274if model_class is TFEsmForMaskedLM:
275# Output embedding test differs from the main test because they're a matrix, not a layer
276name = model.get_bias()
277assert isinstance(name, dict)
278for k, v in name.items():
279assert isinstance(v, tf.Variable)
280else:
281x = model.get_output_embeddings()
282assert x is None
283name = model.get_bias()
284assert name is None
285
286
287@require_tf
288class TFEsmModelIntegrationTest(unittest.TestCase):
289@slow
290def test_inference_masked_lm(self):
291model = TFEsmForMaskedLM.from_pretrained("facebook/esm2_t6_8M_UR50D")
292
293input_ids = tf.constant([[0, 1, 2, 3, 4, 5]])
294output = model(input_ids)[0]
295expected_shape = [1, 6, 33]
296self.assertEqual(list(output.numpy().shape), expected_shape)
297# compare the actual values for a slice.
298expected_slice = tf.constant(
299[
300[
301[8.921518, -10.589814, -6.4671307],
302[-6.3967156, -13.911377, -1.1211915],
303[-7.781247, -13.951557, -3.740592],
304]
305]
306)
307self.assertTrue(numpy.allclose(output[:, :3, :3].numpy(), expected_slice.numpy(), atol=1e-2))
308
309@slow
310def test_inference_no_head(self):
311model = TFEsmModel.from_pretrained("facebook/esm2_t6_8M_UR50D")
312
313input_ids = tf.constant([[0, 6, 4, 13, 5, 4, 16, 12, 11, 7, 2]])
314output = model(input_ids)[0]
315# compare the actual values for a slice.
316expected_slice = tf.constant(
317[
318[
319[0.14443092, 0.54125327, 0.3247739],
320[0.30340484, 0.00526676, 0.31077722],
321[0.32278043, -0.24987096, 0.3414628],
322]
323]
324)
325self.assertTrue(numpy.allclose(output[:, :3, :3].numpy(), expected_slice.numpy(), atol=1e-4))
326