transformers
729 строк · 32.1 Кб
1# coding=utf-8
2# Copyright 2019 HuggingFace Inc.
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 annotations18
19import inspect20import json21import os22import random23import tempfile24import unittest25import unittest.mock as mock26
27from huggingface_hub import HfFolder, Repository, delete_repo, snapshot_download28from huggingface_hub.file_download import http_get29from requests.exceptions import HTTPError30
31from transformers import is_tf_available, is_torch_available32from transformers.configuration_utils import PretrainedConfig33from transformers.testing_utils import ( # noqa: F40134TOKEN,35USER,36CaptureLogger,37_tf_gpu_memory_limit,38is_pt_tf_cross_test,39is_staging_test,40require_safetensors,41require_tf,42require_torch,43slow,44)
45from transformers.utils import SAFE_WEIGHTS_NAME, TF2_WEIGHTS_INDEX_NAME, TF2_WEIGHTS_NAME, logging46
47
48logger = logging.get_logger(__name__)49
50
51if is_tf_available():52import h5py53import numpy as np54import tensorflow as tf55
56from transformers import (57BertConfig,58PreTrainedModel,59PushToHubCallback,60RagRetriever,61TFBertForMaskedLM,62TFBertForSequenceClassification,63TFBertModel,64TFPreTrainedModel,65TFRagModel,66)67from transformers.modeling_tf_utils import keras, tf_shard_checkpoint, unpack_inputs68from transformers.tf_utils import stable_softmax69
70tf.config.experimental.enable_tensor_float_32_execution(False)71
72if _tf_gpu_memory_limit is not None:73gpus = tf.config.list_physical_devices("GPU")74for gpu in gpus:75# Restrict TensorFlow to only allocate x GB of memory on the GPUs76try:77tf.config.set_logical_device_configuration(78gpu, [tf.config.LogicalDeviceConfiguration(memory_limit=_tf_gpu_memory_limit)]79)80logical_gpus = tf.config.list_logical_devices("GPU")81print("Logical GPUs", logical_gpus)82except RuntimeError as e:83# Virtual devices must be set before GPUs have been initialized84print(e)85
86if is_torch_available():87from transformers import BertModel88
89
90@require_tf
91class TFModelUtilsTest(unittest.TestCase):92def test_cached_files_are_used_when_internet_is_down(self):93# A mock response for an HTTP head request to emulate server down94response_mock = mock.Mock()95response_mock.status_code = 50096response_mock.headers = {}97response_mock.raise_for_status.side_effect = HTTPError98response_mock.json.return_value = {}99
100# Download this model to make sure it's in the cache.101_ = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert")102
103# Under the mock environment we get a 500 error when trying to reach the model.104with mock.patch("requests.Session.request", return_value=response_mock) as mock_head:105_ = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert")106# This check we did call the fake head request107mock_head.assert_called()108
109def test_load_from_one_file(self):110try:111tmp_file = tempfile.mktemp()112with open(tmp_file, "wb") as f:113http_get("https://huggingface.co/hf-internal-testing/tiny-random-bert/resolve/main/tf_model.h5", f)114
115config = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert")116_ = TFBertModel.from_pretrained(tmp_file, config=config)117finally:118os.remove(tmp_file)119
120def test_legacy_load_from_url(self):121# This test is for deprecated behavior and can be removed in v5122config = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert")123_ = TFBertModel.from_pretrained(124"https://huggingface.co/hf-internal-testing/tiny-random-bert/resolve/main/tf_model.h5", config=config125)126
127# tests whether the unpack_inputs function behaves as expected128def test_unpack_inputs(self):129class DummyModel:130def __init__(self):131config_kwargs = {"output_attentions": False, "output_hidden_states": False, "return_dict": False}132self.config = PretrainedConfig(**config_kwargs)133self.main_input_name = "input_ids"134
135@unpack_inputs136def call(137self,138input_ids=None,139past_key_values=None,140output_attentions=None,141output_hidden_states=None,142return_dict=None,143):144return input_ids, past_key_values, output_attentions, output_hidden_states, return_dict145
146@unpack_inputs147def foo(self, pixel_values, output_attentions=None, output_hidden_states=None, return_dict=None):148return pixel_values, output_attentions, output_hidden_states, return_dict149
150dummy_model = DummyModel()151input_ids = tf.constant([0, 1, 2, 3], dtype=tf.int32)152past_key_values = tf.constant([4, 5, 6, 7], dtype=tf.int32)153pixel_values = tf.constant([8, 9, 10, 11], dtype=tf.int32)154
155# test case 1: Pass inputs as keyword arguments; Booleans are inherited from the config.156output = dummy_model.call(input_ids=input_ids, past_key_values=past_key_values)157tf.debugging.assert_equal(output[0], input_ids)158tf.debugging.assert_equal(output[1], past_key_values)159self.assertFalse(output[2])160self.assertFalse(output[3])161self.assertFalse(output[4])162
163# test case 2: Same as above, but with positional arguments.164output = dummy_model.call(input_ids, past_key_values)165tf.debugging.assert_equal(output[0], input_ids)166tf.debugging.assert_equal(output[1], past_key_values)167self.assertFalse(output[2])168self.assertFalse(output[3])169self.assertFalse(output[4])170
171# test case 3: We can also pack everything in the first input.172output = dummy_model.call(input_ids={"input_ids": input_ids, "past_key_values": past_key_values})173tf.debugging.assert_equal(output[0], input_ids)174tf.debugging.assert_equal(output[1], past_key_values)175self.assertFalse(output[2])176self.assertFalse(output[3])177self.assertFalse(output[4])178
179# test case 4: Explicit boolean arguments should override the config.180output = dummy_model.call(181input_ids=input_ids, past_key_values=past_key_values, output_attentions=False, return_dict=True182)183tf.debugging.assert_equal(output[0], input_ids)184tf.debugging.assert_equal(output[1], past_key_values)185self.assertFalse(output[2])186self.assertFalse(output[3])187self.assertTrue(output[4])188
189# test case 5: Unexpected arguments should raise an exception.190with self.assertRaises(ValueError):191output = dummy_model.call(input_ids=input_ids, past_key_values=past_key_values, foo="bar")192
193# test case 6: the decorator is independent from `main_input_name` -- it treats the first argument of the194# decorated function as its main input.195output = dummy_model.foo(pixel_values=pixel_values)196tf.debugging.assert_equal(output[0], pixel_values)197self.assertFalse(output[1])198self.assertFalse(output[2])199self.assertFalse(output[3])200
201# Tests whether the stable softmax is stable on CPU, with and without XLA202def test_xla_stable_softmax(self):203large_penalty = -1e9204n_tokens = 10205batch_size = 8206
207def masked_softmax(x, boolean_mask):208numerical_mask = (1.0 - tf.cast(boolean_mask, dtype=tf.float32)) * large_penalty209masked_x = x + numerical_mask210return stable_softmax(masked_x)211
212xla_masked_softmax = tf.function(masked_softmax, jit_compile=True)213xla_stable_softmax = tf.function(stable_softmax, jit_compile=True)214x = tf.random.normal((batch_size, n_tokens))215
216# Same outcome regardless of the boolean mask here217masked_tokens = random.randint(0, n_tokens)218boolean_mask = tf.convert_to_tensor([[1] * (n_tokens - masked_tokens) + [0] * masked_tokens], dtype=tf.int32)219
220# We can randomly mask a random numerical input OUTSIDE XLA221numerical_mask = (1.0 - tf.cast(boolean_mask, dtype=tf.float32)) * large_penalty222masked_x = x + numerical_mask223xla_out = xla_stable_softmax(masked_x)224out = stable_softmax(masked_x)225assert tf.experimental.numpy.allclose(xla_out, out)226
227# The stable softmax has the same output as the original softmax228unstable_out = tf.nn.softmax(masked_x)229assert tf.experimental.numpy.allclose(unstable_out, out)230
231# We can randomly mask a random numerical input INSIDE XLA232xla_out = xla_masked_softmax(x, boolean_mask)233out = masked_softmax(x, boolean_mask)234assert tf.experimental.numpy.allclose(xla_out, out)235
236def test_checkpoint_sharding_from_hub(self):237model = TFBertModel.from_pretrained("ArthurZ/tiny-random-bert-sharded")238# the model above is the same as the model below, just a sharded version.239ref_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert")240for p1, p2 in zip(model.weights, ref_model.weights):241assert np.allclose(p1.numpy(), p2.numpy())242
243def test_sharded_checkpoint_with_prefix(self):244model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert", load_weight_prefix="a/b")245sharded_model = TFBertModel.from_pretrained("ArthurZ/tiny-random-bert-sharded", load_weight_prefix="a/b")246for p1, p2 in zip(model.weights, sharded_model.weights):247self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))248self.assertTrue(p1.name.startswith("a/b/"))249self.assertTrue(p2.name.startswith("a/b/"))250
251def test_sharded_checkpoint_transfer(self):252# If this doesn't throw an error then the test passes253TFBertForSequenceClassification.from_pretrained("ArthurZ/tiny-random-bert-sharded")254
255@is_pt_tf_cross_test256def test_checkpoint_sharding_local_from_pt(self):257with tempfile.TemporaryDirectory() as tmp_dir:258_ = Repository(local_dir=tmp_dir, clone_from="hf-internal-testing/tiny-random-bert-sharded")259model = TFBertModel.from_pretrained(tmp_dir, from_pt=True)260# the model above is the same as the model below, just a sharded pytorch version.261ref_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert")262for p1, p2 in zip(model.weights, ref_model.weights):263assert np.allclose(p1.numpy(), p2.numpy())264
265@is_pt_tf_cross_test266def test_checkpoint_loading_with_prefix_from_pt(self):267model = TFBertModel.from_pretrained(268"hf-internal-testing/tiny-random-bert", from_pt=True, load_weight_prefix="a/b"269)270ref_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert", from_pt=True)271for p1, p2 in zip(model.weights, ref_model.weights):272self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))273self.assertTrue(p1.name.startswith("a/b/"))274
275@is_pt_tf_cross_test276def test_checkpoint_sharding_hub_from_pt(self):277model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert-sharded", from_pt=True)278# the model above is the same as the model below, just a sharded pytorch version.279ref_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert")280for p1, p2 in zip(model.weights, ref_model.weights):281assert np.allclose(p1.numpy(), p2.numpy())282
283def test_shard_checkpoint(self):284# This is the model we will use, total size 340,000 bytes.285model = keras.Sequential(286[287keras.layers.Dense(200, use_bias=False), # size 80,000288keras.layers.Dense(200, use_bias=False), # size 160,000289keras.layers.Dense(100, use_bias=False), # size 80,000290keras.layers.Dense(50, use_bias=False), # size 20,000291]292)293inputs = tf.zeros((1, 100), dtype=tf.float32)294model(inputs)295weights = model.weights296weights_dict = {w.name: w for w in weights}297with self.subTest("No shard when max size is bigger than model size"):298shards, index = tf_shard_checkpoint(weights)299self.assertIsNone(index)300self.assertDictEqual(shards, {TF2_WEIGHTS_NAME: weights})301
302with self.subTest("Test sharding, no weights bigger than max size"):303shards, index = tf_shard_checkpoint(weights, max_shard_size="300kB")304# Split is first two layers then last two.305self.assertDictEqual(306index,307{308"metadata": {"total_size": 340000},309"weight_map": {310"dense/kernel:0": "tf_model-00001-of-00002.h5",311"dense_1/kernel:0": "tf_model-00001-of-00002.h5",312"dense_2/kernel:0": "tf_model-00002-of-00002.h5",313"dense_3/kernel:0": "tf_model-00002-of-00002.h5",314},315},316)317
318shard1 = [weights_dict["dense/kernel:0"], weights_dict["dense_1/kernel:0"]]319shard2 = [weights_dict["dense_2/kernel:0"], weights_dict["dense_3/kernel:0"]]320self.assertDictEqual(shards, {"tf_model-00001-of-00002.h5": shard1, "tf_model-00002-of-00002.h5": shard2})321
322with self.subTest("Test sharding with weights bigger than max size"):323shards, index = tf_shard_checkpoint(weights, max_shard_size="100kB")324# Split is first layer, second layer then last 2.325self.assertDictEqual(326index,327{328"metadata": {"total_size": 340000},329"weight_map": {330"dense/kernel:0": "tf_model-00001-of-00003.h5",331"dense_1/kernel:0": "tf_model-00002-of-00003.h5",332"dense_2/kernel:0": "tf_model-00003-of-00003.h5",333"dense_3/kernel:0": "tf_model-00003-of-00003.h5",334},335},336)337
338shard1 = [weights_dict["dense/kernel:0"]]339shard2 = [weights_dict["dense_1/kernel:0"]]340shard3 = [weights_dict["dense_2/kernel:0"], weights_dict["dense_3/kernel:0"]]341self.assertDictEqual(342shards,343{344"tf_model-00001-of-00003.h5": shard1,345"tf_model-00002-of-00003.h5": shard2,346"tf_model-00003-of-00003.h5": shard3,347},348)349
350@slow351def test_special_layer_name_sharding(self):352retriever = RagRetriever.from_pretrained("facebook/rag-token-nq", index_name="exact", use_dummy_dataset=True)353model = TFRagModel.from_pretrained("facebook/rag-token-nq", retriever=retriever)354
355with tempfile.TemporaryDirectory() as tmp_dir:356for max_size in ["150kB", "150kiB", "200kB", "200kiB"]:357model.save_pretrained(tmp_dir, max_shard_size=max_size)358ref_model = TFRagModel.from_pretrained(tmp_dir, retriever=retriever)359for p1, p2 in zip(model.weights, ref_model.weights):360assert np.allclose(p1.numpy(), p2.numpy())361
362def test_checkpoint_sharding_local(self):363model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert")364
365with tempfile.TemporaryDirectory() as tmp_dir:366# We use the same folder for various sizes to make sure a new save erases the old checkpoint.367for max_size in ["150kB", "150kiB", "200kB", "200kiB"]:368model.save_pretrained(tmp_dir, max_shard_size=max_size)369
370# Get each shard file and its size371shard_to_size = {}372for shard in os.listdir(tmp_dir):373if shard.endswith(".h5"):374shard_file = os.path.join(tmp_dir, shard)375shard_to_size[shard_file] = os.path.getsize(shard_file)376
377index_file = os.path.join(tmp_dir, TF2_WEIGHTS_INDEX_NAME)378# Check there is an index but no regular weight file379self.assertTrue(os.path.isfile(index_file))380self.assertFalse(os.path.isfile(os.path.join(tmp_dir, TF2_WEIGHTS_NAME)))381
382# Check a file is bigger than max_size only when it has a single weight383for shard_file, size in shard_to_size.items():384if max_size.endswith("kiB"):385max_size_int = int(max_size[:-3]) * 2**10386else:387max_size_int = int(max_size[:-2]) * 10**3388# Note: pickle adds some junk so the weight of the file can end up being slightly bigger than389# the size asked for (since we count parameters)390if size >= max_size_int + 50000:391with h5py.File(shard_file, "r") as state_file:392self.assertEqual(len(state_file), 1)393
394# Check the index and the shard files found match395with open(index_file, "r", encoding="utf-8") as f:396index = json.loads(f.read())397
398all_shards = set(index["weight_map"].values())399shards_found = {f for f in os.listdir(tmp_dir) if f.endswith(".h5")}400self.assertSetEqual(all_shards, shards_found)401
402# Finally, check the model can be reloaded403new_model = TFBertModel.from_pretrained(tmp_dir)404
405model.build_in_name_scope()406new_model.build_in_name_scope()407
408for p1, p2 in zip(model.weights, new_model.weights):409self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))410
411@slow412def test_save_pretrained_signatures(self):413model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert")414
415# Short custom TF signature function.416# `input_signature` is specific to BERT.417@tf.function(418input_signature=[419[420tf.TensorSpec([None, None], tf.int32, name="input_ids"),421tf.TensorSpec([None, None], tf.int32, name="token_type_ids"),422tf.TensorSpec([None, None], tf.int32, name="attention_mask"),423]424]425)426def serving_fn(input):427return model(input)428
429# Using default signature (default behavior) overrides 'serving_default'430with tempfile.TemporaryDirectory() as tmp_dir:431model.save_pretrained(tmp_dir, saved_model=True, signatures=None)432model_loaded = keras.models.load_model(f"{tmp_dir}/saved_model/1")433self.assertTrue("serving_default" in list(model_loaded.signatures.keys()))434
435# Providing custom signature function436with tempfile.TemporaryDirectory() as tmp_dir:437model.save_pretrained(tmp_dir, saved_model=True, signatures={"custom_signature": serving_fn})438model_loaded = keras.models.load_model(f"{tmp_dir}/saved_model/1")439self.assertTrue("custom_signature" in list(model_loaded.signatures.keys()))440
441# Providing multiple custom signature function442with tempfile.TemporaryDirectory() as tmp_dir:443model.save_pretrained(444tmp_dir,445saved_model=True,446signatures={"custom_signature_1": serving_fn, "custom_signature_2": serving_fn},447)448model_loaded = keras.models.load_model(f"{tmp_dir}/saved_model/1")449self.assertTrue("custom_signature_1" in list(model_loaded.signatures.keys()))450self.assertTrue("custom_signature_2" in list(model_loaded.signatures.keys()))451
452@require_safetensors453def test_safetensors_save_and_load(self):454model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert")455with tempfile.TemporaryDirectory() as tmp_dir:456model.save_pretrained(tmp_dir, safe_serialization=True)457# No tf_model.h5 file, only a model.safetensors458self.assertTrue(os.path.isfile(os.path.join(tmp_dir, SAFE_WEIGHTS_NAME)))459self.assertFalse(os.path.isfile(os.path.join(tmp_dir, TF2_WEIGHTS_NAME)))460
461new_model = TFBertModel.from_pretrained(tmp_dir)462
463# Check models are equal464for p1, p2 in zip(model.weights, new_model.weights):465self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))466
467@is_pt_tf_cross_test468def test_safetensors_save_and_load_pt_to_tf(self):469model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert")470pt_model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert")471with tempfile.TemporaryDirectory() as tmp_dir:472pt_model.save_pretrained(tmp_dir, safe_serialization=True)473# Check we have a model.safetensors file474self.assertTrue(os.path.isfile(os.path.join(tmp_dir, SAFE_WEIGHTS_NAME)))475
476new_model = TFBertModel.from_pretrained(tmp_dir)477
478# Check models are equal479for p1, p2 in zip(model.weights, new_model.weights):480self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))481
482@require_safetensors483def test_safetensors_load_from_hub(self):484tf_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert")485
486# Can load from the TF-formatted checkpoint487safetensors_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert-safetensors-tf")488
489# Check models are equal490for p1, p2 in zip(safetensors_model.weights, tf_model.weights):491self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))492
493# Can load from the PyTorch-formatted checkpoint494safetensors_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert-safetensors")495
496# Check models are equal497for p1, p2 in zip(safetensors_model.weights, tf_model.weights):498self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))499
500@require_safetensors501def test_safetensors_tf_from_tf(self):502model = TFBertModel.from_pretrained("hf-internal-testing/tiny-bert-tf-only")503
504with tempfile.TemporaryDirectory() as tmp_dir:505model.save_pretrained(tmp_dir, safe_serialization=True)506new_model = TFBertModel.from_pretrained(tmp_dir)507
508for p1, p2 in zip(model.weights, new_model.weights):509self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))510
511@require_safetensors512@is_pt_tf_cross_test513def test_safetensors_tf_from_torch(self):514hub_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-bert-tf-only")515model = BertModel.from_pretrained("hf-internal-testing/tiny-bert-pt-only")516
517with tempfile.TemporaryDirectory() as tmp_dir:518model.save_pretrained(tmp_dir, safe_serialization=True)519new_model = TFBertModel.from_pretrained(tmp_dir)520
521for p1, p2 in zip(hub_model.weights, new_model.weights):522self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))523
524@require_safetensors525def test_safetensors_tf_from_sharded_h5_with_sharded_safetensors_local(self):526with tempfile.TemporaryDirectory() as tmp_dir:527path = snapshot_download("hf-internal-testing/tiny-bert-tf-safetensors-h5-sharded", cache_dir=tmp_dir)528
529# This should not raise even if there are two types of sharded weights530TFBertModel.from_pretrained(path)531
532@require_safetensors533def test_safetensors_tf_from_sharded_h5_with_sharded_safetensors_hub(self):534# This should not raise even if there are two types of sharded weights535# This should discard the safetensors weights in favor of the .h5 sharded weights536TFBertModel.from_pretrained("hf-internal-testing/tiny-bert-tf-safetensors-h5-sharded")537
538@require_safetensors539def test_safetensors_load_from_local(self):540"""541This test checks that we can load safetensors from a checkpoint that only has those on the Hub
542"""
543with tempfile.TemporaryDirectory() as tmp:544location = snapshot_download("hf-internal-testing/tiny-bert-tf-only", cache_dir=tmp)545tf_model = TFBertModel.from_pretrained(location)546
547with tempfile.TemporaryDirectory() as tmp:548location = snapshot_download("hf-internal-testing/tiny-bert-tf-safetensors-only", cache_dir=tmp)549safetensors_model = TFBertModel.from_pretrained(location)550
551for p1, p2 in zip(tf_model.weights, safetensors_model.weights):552self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))553
554@require_safetensors555def test_safetensors_load_from_hub_from_safetensors_pt(self):556"""557This test checks that we can load safetensors from a checkpoint that only has those on the Hub.
558saved in the "pt" format.
559"""
560tf_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-bert-h5")561
562# Can load from the PyTorch-formatted checkpoint563safetensors_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-bert-pt-safetensors")564for p1, p2 in zip(tf_model.weights, safetensors_model.weights):565self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))566
567@require_safetensors568def test_safetensors_load_from_local_from_safetensors_pt(self):569"""570This test checks that we can load safetensors from a local checkpoint that only has those
571saved in the "pt" format.
572"""
573with tempfile.TemporaryDirectory() as tmp:574location = snapshot_download("hf-internal-testing/tiny-bert-h5", cache_dir=tmp)575tf_model = TFBertModel.from_pretrained(location)576
577# Can load from the PyTorch-formatted checkpoint578with tempfile.TemporaryDirectory() as tmp:579location = snapshot_download("hf-internal-testing/tiny-bert-pt-safetensors", cache_dir=tmp)580safetensors_model = TFBertModel.from_pretrained(location)581
582for p1, p2 in zip(tf_model.weights, safetensors_model.weights):583self.assertTrue(np.allclose(p1.numpy(), p2.numpy()))584
585@require_safetensors586def test_safetensors_load_from_hub_h5_before_safetensors(self):587"""588This test checks that we'll first download h5 weights before safetensors
589The safetensors file on that repo is a pt safetensors and therefore cannot be loaded without PyTorch
590"""
591TFBertModel.from_pretrained("hf-internal-testing/tiny-bert-pt-safetensors-msgpack")592
593@require_safetensors594def test_safetensors_load_from_local_h5_before_safetensors(self):595"""596This test checks that we'll first download h5 weights before safetensors
597The safetensors file on that repo is a pt safetensors and therefore cannot be loaded without PyTorch
598"""
599with tempfile.TemporaryDirectory() as tmp:600location = snapshot_download("hf-internal-testing/tiny-bert-pt-safetensors-msgpack", cache_dir=tmp)601TFBertModel.from_pretrained(location)602
603
604@require_tf
605@is_staging_test
606class TFModelPushToHubTester(unittest.TestCase):607@classmethod608def setUpClass(cls):609cls._token = TOKEN610HfFolder.save_token(TOKEN)611
612@classmethod613def tearDownClass(cls):614try:615delete_repo(token=cls._token, repo_id="test-model-tf")616except HTTPError:617pass618
619try:620delete_repo(token=cls._token, repo_id="test-model-tf-callback")621except HTTPError:622pass623
624try:625delete_repo(token=cls._token, repo_id="valid_org/test-model-tf-org")626except HTTPError:627pass628
629def test_push_to_hub(self):630config = BertConfig(631vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37632)633model = TFBertModel(config)634# Make sure model is properly initialized635model.build_in_name_scope()636
637logging.set_verbosity_info()638logger = logging.get_logger("transformers.utils.hub")639with CaptureLogger(logger) as cl:640model.push_to_hub("test-model-tf", token=self._token)641logging.set_verbosity_warning()642# Check the model card was created and uploaded.643self.assertIn("Uploading the following files to __DUMMY_TRANSFORMERS_USER__/test-model-tf", cl.out)644
645new_model = TFBertModel.from_pretrained(f"{USER}/test-model-tf")646models_equal = True647for p1, p2 in zip(model.weights, new_model.weights):648if not tf.math.reduce_all(p1 == p2):649models_equal = False650break651self.assertTrue(models_equal)652
653# Reset repo654delete_repo(token=self._token, repo_id="test-model-tf")655
656# Push to hub via save_pretrained657with tempfile.TemporaryDirectory() as tmp_dir:658model.save_pretrained(tmp_dir, repo_id="test-model-tf", push_to_hub=True, token=self._token)659
660new_model = TFBertModel.from_pretrained(f"{USER}/test-model-tf")661models_equal = True662for p1, p2 in zip(model.weights, new_model.weights):663if not tf.math.reduce_all(p1 == p2):664models_equal = False665break666self.assertTrue(models_equal)667
668@is_pt_tf_cross_test669def test_push_to_hub_callback(self):670config = BertConfig(671vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37672)673model = TFBertForMaskedLM(config)674model.compile()675
676with tempfile.TemporaryDirectory() as tmp_dir:677push_to_hub_callback = PushToHubCallback(678output_dir=tmp_dir,679hub_model_id="test-model-tf-callback",680hub_token=self._token,681)682model.fit(model.dummy_inputs, model.dummy_inputs, epochs=1, callbacks=[push_to_hub_callback])683
684new_model = TFBertForMaskedLM.from_pretrained(f"{USER}/test-model-tf-callback")685models_equal = True686for p1, p2 in zip(model.weights, new_model.weights):687if not tf.math.reduce_all(p1 == p2):688models_equal = False689break690self.assertTrue(models_equal)691
692tf_push_to_hub_params = dict(inspect.signature(TFPreTrainedModel.push_to_hub).parameters)693tf_push_to_hub_params.pop("base_model_card_args")694pt_push_to_hub_params = dict(inspect.signature(PreTrainedModel.push_to_hub).parameters)695pt_push_to_hub_params.pop("deprecated_kwargs")696self.assertDictEaual(tf_push_to_hub_params, pt_push_to_hub_params)697
698def test_push_to_hub_in_organization(self):699config = BertConfig(700vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37701)702model = TFBertModel(config)703# Make sure model is properly initialized704model.build_in_name_scope()705
706model.push_to_hub("valid_org/test-model-tf-org", token=self._token)707
708new_model = TFBertModel.from_pretrained("valid_org/test-model-tf-org")709models_equal = True710for p1, p2 in zip(model.weights, new_model.weights):711if not tf.math.reduce_all(p1 == p2):712models_equal = False713break714self.assertTrue(models_equal)715
716# Reset repo717delete_repo(token=self._token, repo_id="valid_org/test-model-tf-org")718
719# Push to hub via save_pretrained720with tempfile.TemporaryDirectory() as tmp_dir:721model.save_pretrained(tmp_dir, push_to_hub=True, token=self._token, repo_id="valid_org/test-model-tf-org")722
723new_model = TFBertModel.from_pretrained("valid_org/test-model-tf-org")724models_equal = True725for p1, p2 in zip(model.weights, new_model.weights):726if not tf.math.reduce_all(p1 == p2):727models_equal = False728break729self.assertTrue(models_equal)730